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

Tom Wainwright tcw@|nw @end|ng |rom gm@||@com
Mon Jun 22 21:48:49 CEST 2020


Yet another alternative is simply to prevent your second package from
overriding the previously defined generic. The basic problem is the ease
with which R allows overriding prior generic definitions (one of those bits
of bad behavior we in the USA used to call "a Bozo No-No"), which hides all
the previous methods, as demonstrated by the following code:

> plot(1:3)
> > plot <- function(x, ...) UseMethod("plot")
> > plot(1:3)
> Error in UseMethod("plot") :
>   no applicable method for 'plot' applied to an object of class
> "c('integer', 'numeric')"
> > rm(plot)
> > plot(1:3)


(Despite Murdoch's suggestion that overriding the generic SHOULD issue a
warning, it doesn't seem to in R 4.0.1.)

So, we might try protecting the generic definitions of "foo" in both
packages by enclosing them in something like:

tryCatch(invisible(methods("foo")), error = {foo <- function(x,...)
> UseMethod("foo")}, finally=NULL)


There's probably a more elegant way to accomplish this. This relies on
"methods" returning an error if "foo" has no defined methods, so it is not
redefined if their are previous methods. I haven't had time to try this in
the two-package example, but it might work, although I'm not sure how to
handle the Namespace declarations.

  Tom Wainwright

On Mon, Jun 22, 2020 at 10:41 AM Bert Gunter <bgunter.4567 using gmail.com> wrote:

> ...
> and just to add to the query, assume the author of pkg B did (does) not
> know of pkg A and so, for example, could (did) not import any of pkg A's
> content into B. Given that there are at the moment ~20,000 packages out
> there, this does not seem to be an unreasonable assumption. One may even
> further assume that the user may not know that (s)he has package B loaded,
> as it may be a dependency of another package that (s)he uses. I certainly
> don't keep track of all the dependencies of packages I use.
>
> Under these assumptions, is there any more convenient alternative to
> Wolfgang's pkgA:foo(x) explicit call under such assumptions? If pkgA has a
> long name, what might one do?
>
> Bert Gunter
>
> "The trouble with having an open mind is that people keep coming along and
> sticking things into it."
> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
>
>
> On Mon, Jun 22, 2020 at 10:00 AM Viechtbauer, Wolfgang (SP) <
> wolfgang.viechtbauer using maastrichtuniversity.nl> 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)
> > 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.
> >
> > Best,
> > Wolfgang
> >
> > ______________________________________________
> > R-package-devel using r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-package-devel
> >
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>

	[[alternative HTML version deleted]]



More information about the R-package-devel mailing list