Skip to content
Prev 3912 / 12125 Next

[R-pkg-devel] Three-argument S3method declaration does not seem to affect dispatching from inside the package.

Dear All,

I've run into this while updating a package with unfortunately named
legacy functions. It seems like something that might be worth changing
in R, and I want to get a sense of whether this is a problem before
submitting a report to the Bugzilla.

It appears that the 3-argument form of S3method() in NAMESPACE controls
dispatching when the generic is called from outside the package that
defines it but not when it's called from inside the package that
defines it.

For example the attached minimal package has four R functions:

   gen <- function(object, ...)
     UseMethod("gen")

   .gen.formula <- function(object, ...){
     message("I am the S3method-declared method.")
   }

   gen.formula <- function(object, ...){
     message("I am the function with an unfortunate name.")
   }

   test_me <- function(){
     message("I am the tester. Which one will I call?")
     gen(a~b)
   }

and the following NAMESPACE:

   export(gen)
   S3method(gen, formula, .gen.formula)
   export(gen.formula)
   export(test_me)

Now,

   library(anRpackage)
   example(test_me)

results in the following:

   test_m> test_me
   function(){
     message("I am the tester. Which one will I call?")
     gen(a~b)
   }
   <bytecode: 0x562fb9d32d68>
   <environment: namespace:anRpackage>

   test_m> test_me() # Calls gen.formula()
   I am the tester. Which one will I call?
   I am the function with an unfortunate name.

   test_m> gen(a~b) # Calls .gen.formula()
   I am the S3method-declared method.

So, calling the same generic function with the same class results in
different dispatching behaviour depending on whether the call is from
within the package doing the export or from the outside.

This behaviour appears to be as documented ( 
https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Method-dispatching
), but it seems to me that if S3method() is allowed to give the name of
the method to be used, then it should should override the name-based
dispatching both inside and outside the package.

			Any thoughts?
			Pavel Krivitsky