Перегрузка операторов при использовании setOldClass не работает по желанию по сравнению с классом S4

Может кто-нибудь объяснить, почему перегрузка оператора в старом стилевом классе S3, который зарегистрирован, не работает должным образом, когда при определении нового класса и перегрузке операторы работают.

Как показано в следующих примерах.

Это не работает.

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

Но это работает.

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

Ответ 1

Попытка частичного ответа: В справке ( "Методы" ) в разделе Общие функции указано:

Методы могут быть определены для большинства примитивов, а соответствующие метаданные объекты будут созданы для их хранения. Звонки на примитив все еще идут непосредственно на C-код, который иногда проверяет применимые методы. Определение "иногда" заключается в том, что методы должны были быть обнаружено для функции в некотором пакете, загруженном в сеанс и isS4 (x) имеет значение TRUE для первого аргумента (или для второго аргумента в случай бинарных операторов).

Вернемся к вашей проблеме, * является примитивным и:

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

Итак, из того, что я понимаю, невозможно определить метод для примитивных функций на классах S3, даже если вы используете setOldClass().

Ответ 2

Не совсем ясно из вопроса, считается ли это ответом, но для записи оператор может быть перегружен простым и простым S3-стилем без каких-либо setOldClass или 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