2

I have some trouble understanding the differences in method dispatching between S3 and S4 classes. As far as I understand, S3 classes use UseMethod and finds the correct method via the class attribute of the object passed. S4 classes use StandardGeneric and work with function signatures (I'm reading Advanced R). But the following code runs:

myfun <- function(x, y = NULL) {
  UseMethod("myfun")
}

myfun.default <- function(x, y) {
  print("default method")
}

myfun.integer <- function(x, y) {
  print("S3 dispatch for integer")
}

setMethod("myfun",
          signature = c(x = "matrix", y = "ANY"),
          function(x, y) {
            print("S4 dispatch for matrices")
          }
)

setMethod("myfun",
          signature = c(x = "character", y = "ANY"),
          function(x, y) {
            print("S4 dispatch for strings")
          }
)

setMethod("myfun",
          signature = c(x = "character", y = "character"),
          function(x, y) {
            print("S4 dispatch for string + string")
          }
)

myfun(iris)
## [1] "default method"
myfun(1:10)
## [1] "S3 dispatch for integer"
myfun(matrix(0, nrow = 2, ncol = 2))
## [1] "S4 dispatch for matrices"
myfun("foo")
## [1] "S4 dispatch for strings"
myfun("foo", y = "bar")
## [1] "S4 dispatch for string + string"

What exactly is going on here? I created an S3 method called "myfun", for which the S3 method dispatch works as intended. So far, so good.

But this S3 method also correctly dispatches S4 methods, even though I didn't define a StandardGeneric for these S4 methods (or convert myfun to such). How come? Any background would be appreciated.

Thanks in advance!

ahanf
  • 59
  • 1
  • 7

0 Answers0