2013-04-10 10 views
10

Czy ktoś może wyjaśnić, dlaczego przeciążenie operatora w starej klasie S3, która jest zarejestrowana, nie działa zgodnie z oczekiwaniami, podczas definiowania nowej klasy i przeciążania operatorów praca.przeciążanie operatorów, gdy setOldClass nie działa zgodnie z oczekiwaniami w porównaniu do klasy S4

Jak pokazano w poniższych przykładach.

To nie działa.

require(ff) 
setOldClass(Classes=c("ff_vector")) 
setMethod( 
    f="*", 
    signature = signature(e1 = c("ff_vector"), e2 = c("ff_vector")), 
    definition = function (e1, e2){ 
     print("S3 setOldClass") 
     e1[] * e2[] 
    } 
) 
ff(1:10) * ff(1:10) 
Error in ff(1:10) * ff(1:10) : non-numeric argument to binary operator 

Ale to działa.

setClass("myff_vector", representation(x="ff_vector")) 
setMethod( 
    f="*", 
    signature = signature(e1 = c("myff_vector"), e2 = c("myff_vector")), 
    definition = function (e1, e2){ 
     print("S4 setOldClass") 
     [email protected][] * [email protected][] 
    } 
) 
new("myff_vector", x = ff(1:10)) * new("myff_vector", x = ff(1:10)) 
[1] "S4 setOldClass" 
[1] 1 4 9 16 25 36 49 64 81 100 

Odpowiedz

0

Próba częściowej odpowiedzi: W pomocą („Sposoby”), w Generic funkcji sekcji stwierdzono:

metody mogą być zdefiniowane dla większości pierwotnych i odpowiadających metadane zostaną utworzone obiekty do ich przechowywania. Połączenia z prymitywem nadal przechodzą bezpośrednio do kodu C, który czasami sprawdza odpowiednie metody . Definicja "czasami" jest taka, że ​​metody musiały zostać wykryte dla funkcji w jakimś pakiecie załadowanym do sesji, a isS4 (x) to PRAWDA dla pierwszego argumentu (lub dla drugiego argumentu, w przypadku przypadku operatory binarne).

Powrót do Twojego problemu, * jest prymitywne, oraz:

library(ff) 
setOldClass("ff_vector") 
isS4(ff(1:10)) 
[1] FALSE 

Więc z tego co rozumiem, nie jest możliwe określenie sposobu pierwotnych funkcji w klasach S3, nawet jeśli używasz setOldClass().

0

To naprawdę nie wynika z tego, czy to się liczy jako odpowiedź, ale dla przypomnienia, operator może zostać przeciążony w czystym i prostym stylu S3 bez setOldClass lub S4:

`*.ff_vector` <- function(x, y) { 
    print("hi") 
    x[] * y[] 
} 

> ff(1:10) * ff(1:10) 
[1] "hi" 
[1] 1 4 9 16 25 36 49 64 81 100 
Powiązane problemy