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

iuke-tier@ey m@iii@g oii uiow@@edu iuke-tier@ey m@iii@g oii uiow@@edu
Tue Jun 23 04:51:55 CEST 2020


On Tue, 23 Jun 2020, Bert Gunter wrote:

> "Users don't get warned about overriding names in packages they've
> loaded, because that would just be irritating."

All Duncan is saying is that you don't get a notification if you do

     mean <- log

in the interpreter. If you attach a package that does this you would
get a notification (or an error if you configure your conflict
resolution options appropriately).

Best,

luke

>
> Is that also true if the package or generic is imported by another that
> they load; or is a dependency of a package they load? If so, I would not
> call it "just irritating" because if silent, how would they know?
>
>
> 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 5:58 PM Mark Leeds <markleeds2 using gmail.com> wrote:
>
>> Hi Duncan: I maintain dynlm and your example is the exact reason I've been
>> getting emails from people regarding
>> it not working correctly. I've been telling them to load dplyr by using
>>
>> library(dplyr, exclude = c("filter", "lag"))
>>
>>
>>
>>
>>
>> On Mon, Jun 22, 2020 at 7:57 PM Duncan Murdoch <murdoch.duncan using gmail.com>
>> wrote:
>>
>>> On 22/06/2020 3:48 p.m., Tom Wainwright wrote:
>>>> 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.)
>>>
>>> Sure it does, if pkgA and pkgB both export the same name, then you get a
>>> warning when you attach the second one.  For example,
>>>
>>> > library(MASS)
>>> > library(dplyr)
>>>
>>> Attaching package: ‘dplyr’
>>>
>>> The following object is masked from ‘package:MASS’:
>>>
>>>      select
>>>
>>> The following objects are masked from ‘package:stats’:
>>>
>>>      filter, lag
>>>
>>> The following objects are masked from ‘package:base’:
>>>
>>>      intersect, setdiff, setequal, union
>>>
>>> Users don't get warned about overriding names in packages they've
>>> loaded, because that would just be irritating.
>>>
>>> Duncan Murdoch
>>>
>>>>
>>>> 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]]
>>>>
>>>> ______________________________________________
>>>> R-package-devel using r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>>>
>>>
>>> ______________________________________________
>>> 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]]
>
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>

-- 
Luke Tierney
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:   luke-tierney using uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu


More information about the R-package-devel mailing list