[R-pkg-devel] Two packages with the same generic function

Duncan Murdoch murdoch@dunc@n @end|ng |rom gm@||@com
Mon Jun 22 19:38:53 CEST 2020


On 22/06/2020 1:00 p.m., Viechtbauer, Wolfgang (SP) wrote:
> Hi All,
> 
> Let's say there are two packages pkgA and pkgB, both of which have a generic function
> 
> foo <- function(x, ...)
>     UseMethod("foo")
> 
> and pkgA has a method for objects of class "A":
> 
> foo.A <- function(x, ...)
>     print(x)
> 
> and pkgB has a method for objects of class "B":
> 
> foo.B <- function(x, ...)
>     plot(x)
> 
> Both packages export foo and their method and declare their respective S3 methods, so:
> 
> export(foo)
> export(foo.A)
> S3method(foo, A)
> 
> in NAMESPACE of pkgA and
> 
> export(foo)
> export(foo.B)
> S3method(foo, B)
> 
> in NAMESPACE of pkgB.
> 
> If a user loads pkgA first and then pkgB, this fails:
> 
> library(pkgA)
> library(pkgB)

Wouldn't the user have got a warning at this point about pkgB::foo 
masking pkgA::foo?

> x <- 1:4
> class(x) <- "A"
> foo(x)
> 
> Error in UseMethod("foo") :
>    no applicable method for 'foo' applied to an object of class "A"
> 
> and vice-versa. Of course, pkgA::foo(x) works. Aside from pkgA importing foo() or vice-versa, is there some other clever way to make this work? In earlier versions of R (at least in 3.6.3), this used to work (i.e., the generic foo() from pkgB would find method foo.A() and vice-versa), but not since 4.0.0.

Can't one of the packages import the generic from the other package, and 
then declare the method as a method of that other generic?  That seems 
like the only thing that would make sense.  There's no reason to believe 
that pkgA::foo has anything whatsoever to do with pkgB::foo without this.

Duncan Murdoch



More information about the R-package-devel mailing list