2013-04-10 9 views
10

Kann jemand erklären, warum das Überladen eines Operators auf einer alten S3-Klasse, die registriert ist nicht wie erwartet funktioniert, beim Definieren einer neuen Klasse und Überladen der Operatoren Arbeit.Überladen von Operatoren bei Verwendung von setOldClass nicht wie gewünscht funktioniert im Vergleich zu einer S4-Klasse

Wie in den folgenden Beispielen gezeigt.

Dies funktioniert nicht.

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 

Aber das funktioniert.

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 

Antwort

0

Versuch einer Teilantwort: In Hilfe ('Methoden'), in den Allgemeinen Funktionen Abschnitt wird angegeben:

Methoden können für die meisten Grundelemente definiert werden, und die entsprechende Metadaten Objekte werden erstellt, um sie zu speichern. Aufrufe an das Primitive gehen immer noch direkt an den C-Code, der manchmal nach zutreffenden Methoden sucht. Die Definition von "manchmal" ist, dass Methoden für die Funktion in einem Paket in der Sitzung gefunden wurden und isS4 (x) ist TRUE für das erste Argument (oder für das zweite Argument, in der Fall von binäre Operatoren).

Zurück zu Ihrem Problem ist * eine primitive, und:

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

Also von dem, was ich verstehe, ist es nicht möglich ist, ein Verfahren für primitive Funktionen auf S3 Klassen zu definieren, auch wenn Sie verwenden setOldClass().

0

Es ist nicht wirklich von der Frage deutlich, ob dies als eine Antwort zählt, sondern für die Aufzeichnung, könnte der Bediener in schlicht und einfach S3-Stil überlastet werden, ohne setOldClass oder 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 
Verwandte Themen