[R-pkg-devel] Is a double dispatch possible with two S3 classes?

Leonardo Silvestri lsilvestri at ztsdb.org
Thu Feb 16 17:52:56 CET 2017


Hello,

I have stumbled upon an S3 class dispatch issue which is easily solved 
using S4 classes, but I'd like to know if there is a way to solve it 
without changing the type of class used.

The problem is as follows. There is an S3 class 'foo' which is defined 
in a package over which I don't have control. Then there is an S3 class 
'bar' derived from 'foo' in a package that can be modified.

Here is some code for 'foo':

as.foo <- function(x) {
   oldClass(x) <- "foo"
   x
}

print.foo <- function(x, ...) print(paste(x, "foo"))

"-.foo" <- function(e1, e2) "-.foo was called"


And here is some code for 'bar':

as.bar <- function(x) {
   oldClass(x) <- c("bar", "foo")
   x
}

print.bar <- function(x, ...) print(paste(x, "bar"))


Now the '-' operator must be defined in such a way that the behaviour is 
different depending on the operand classes, and in particular 
'bar'-'bar' needs to be different from 'bar'-'foo'. If I define the 
following function:

"-.bar" <- function(e1, e2) "-.bar was called"

then I get the following results.

as.foo(1) - as.foo(2)     # uses '-.foo'
as.bar(1) - as.bar(2)     # uses '-.bar'
as.bar(1) - as.foo(2)     # uses '-.default' and issues
                           # Incompatible methods warning
as.foo(1) - as.bar(2)     # uses '-.default' and issues
                           # Incompatible methods warning

So that seems like a dead end.

If, overcoming an instinctive shudder of disgust, I redefine '-.foo' in 
the "bar" package, I have checked that correctness is at the mercy of 
the order of loading of the packages, even though the "bar" package 
imports the "foo" package. So that doesn't seem to work either.

Before committing to making 'bar' an S4 class, does anyone know if there 
is another option that would allow 'bar' to remain an S3 class?

Thanks,
Leo



More information about the R-package-devel mailing list