Search code examples
roverloading

Fooling R's Method Dispatch


I am looking for an example where a dot in a function name causes R's Method Dispatch to pick the wrong function. A natural candidate seems to be the builtin function t.test(), which should be confused with t() when applied to an object of class "test".

Strangely, however, the following code actually calls the transposition function and not t.test():

> x <- structure(cbind(1:4,2:5), class="test")
> class(x)
[1] "test"
> t(x)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    2    3    4    5

This raises two questions:

  1. Why is the object transposed and not t.test() invoked, as it should be due to the rules of Method Dispatch?
  2. What is a (simple) example for messing up the Method Dispatch process by defining a function with a dot inside?

Solution

  • S3 dispatch is complicated. If you define a function named t.test in the global environment and call t() there on an object with class "test", the t.test() function will be called. However, if t.test is in a package, it needs to be registered as an S3 method to be handled that way. (Registration happens in the NAMESPACE file or by executing registerS3method().)

    So here's an example of what you are looking for:

    t.test <- t.test
    x <- 1
    class(x) <- "test"
    t(x)
    #> Error in t.test.default(x): not enough 'x' observations
    

    Created on 2023-11-14 with reprex v2.0.2

    There was some news about this when R 3.5.0 was released in 2018: the 8th "new feature" from the end in

    https://developer.r-project.org/blosxom.cgi/R-3-5-branch/NEWS/2018/03/29#n2018-03-29