Я хочу перегрузить '*' (оператор умножения) в R при использовании класса S3.
Я вижу, что * уже является универсальным в системе, но я также хочу, чтобы он "generic2", то есть отправлял по второму аргументу.
Вариант использования следующий: скажем, мой класс называется "Struct". Я хочу иметь возможность учесть все эти три случая
Struct * Struct
Struct * Number
Number * Struct
Однако я обнаружил, что если я разрешу диспетчеризацию по второму аргументу, (уже существующая) диспетчеризация по первому аргументу будет отменена!
Есть ли способ, которым я могу сделать это в S3?
# "generic1" already exists for '*'
'*' <- function(x,y){
UseMethod('*2',y)
}
'*.Struct'<-function(x,y){
# must both be structs, so dispatch 'normally' if not
"times(1)"
}
`*2.Struct`<-function(x,y){
# must both be structs, so dispatch 'normally' if not
"times(2)"
}
Дает мне ...
> struct1 * struct2
[1] "times(2)"
> 2 * struct2
[1] "times(2)"
> struct1 * 2
Error in UseMethod("*2", y) :
no applicable method for '*2' applied to an object of class "c('double', 'numeric')"
>
Если я использую это, вместо
'*' <- function(x,y){ UseMethod('*',x)}
Тогда отправка по первому аргументу работает, и происходит обратное:
> struct1 * 2
[1] "times(1)"
> struct1 * struct2
[1] "times(1)"
> 2* struct1
Error in UseMethod("*", x) :
no applicable method for '*' applied to an object of class "c('double', 'numeric')"
>
Похоже, они определенно перезаписывают друг друга.
Есть идеи о том, как оба могут мирно и продуктивно сосуществовать?