I want to overload the '*' (multiplication operator) in R, when using an S3 class.
I see that * is already generic in the system, but I also want it "generic2", i.e. dispatching on the second argument.
The use case is as follows: Say my class is called "Struct". I want to be able to allow for all three of these cases
Struct * Struct
Struct * Number
Number * Struct
However I found that if I allow for dispatching on the second argument, the (already present) dispatching on the first is overridden!
Is there a way that I can do this in 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)"
}
Gives me...
> 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')"
>
If I use this, instead
'*' <- function(x,y){ UseMethod('*',x)}
Then the dispatch on the first argument works, and the opposite happens:
> 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')"
>
So it seems that they're definitely overwriting each other.
Any ideas about how both may coexist peacefully and productively?