[R-pkg-devel] unregistered S3 methods in a package

Uwe Ligges ||gge@ @end|ng |rom @t@t|@t|k@tu-dortmund@de
Thu Sep 5 08:47:06 CEST 2024


Dear John,

the question is not really easy to answer, but there is a nice summary 
Kurt pointed me to: The code of checkS3methods() includes the following 
comments with the last paragraph containing the short answer to your 
question:

     ## Check S3 generics and methods consistency.

     ## Unfortunately, what is an S3 method is not clear.
     ## These days, S3 methods for a generic GEN are found
     ## A. via GEN.CLS lookup from the callenv to its topenv;
     ## B. the S3 registry;
     ## C. GEN.CLS lookup from the parent of the topenv to baseenv,
     ##    skipping everything on the search path between globalenv and
     ##    baseenv.
     ## Thus if "package code" calls GEN, we first look in the package
     ## namespace itself, then in the registry, and then in the package
     ## imports and .BaseNamespaceEnv (and globalenv and baseenv again).
     ##
     ## Clearly, everything registered via S3method() should be an S3
     ## method.  Interestingly, we seem to have some registrations for
     ## non-generics, such as grDevices::axis().  These are "harmless"
     ## but likely not "as intended", and hence inconsistencies are not
     ## ignored.
     ##
     ## If the package namespace has a function named GEN.CLS, it is used
     ## as an S3 method for an S3 generic named GEN (and hence "is an S3
     ## method") only if the package code actually calls GEN (see A
     ## above).  So one could argue that we should not be looking at all
     ## GEN.CLS matches with GEN a generic in the package itself, its
     ## imports or base, but restrict to only the ones where the package
     ## code calls GEN.  Doable, but not straightforward (calls could be
     ## PKG::GEN) and possibly quite time consuming.  For generics from
     ## the package itself or its imports, not restricting should not
     ## make a difference (why define or import when not calling?), but
     ## for generics from base it may: hence we filter out the mismatches
     ## for base GEN not called in the package.
     ##
     ## If a package provides an S3 generic GEN, there is no need to
     ## register GEN.CLS functions for "internal use" (see above).
     ## However, if GEN is exported then likely all GEN.CLS functions
     ## should be registered as S3 methods.


Best wishes,
Uwe


On 05.09.2024 00:10, John Fox wrote:
> Thanks Toby and Jeff for chiming in on this.
> 
> Jeff: I already read Kurt Hornik's post on "S3 Method Lookup" and quite 
> a few other sources.
> 
> The main point is that failing to register the methods works in that the 
> methods are nevertheless invoked internally by functions in the package 
> but don't shadow versions of the methods registered by other package 
> externally (e.g., at the command prompt), which was the effect that I 
> wanted. Moreover, as I said, R CMD check (unlike roxygen) didn't complain.
> 
> As I mentioned, this is now moot for the cv package, but I'm still 
> interested in the answer, as, apparently, is Toby.
> 
> Best,
>   John
> 
> On 2024-09-04 5:12 p.m., Jeff Newmiller wrote:
>> Caution: External email.
>>
>>
>> I have been reluctant to pipe up on this because I am no expert on the 
>> dark corners of the S3 dispatch mechanism, but I think unregistered S3 
>> methods in packages are verboten. Perhaps [1] will shed some light?
>>
>> [1] https://blog.r-project.org/2019/08/19/s3-method-lookup/
>>
>> On September 4, 2024 11:21:22 AM PDT, Toby Hocking <tdhock5 using gmail.com> 
>> wrote:
>>> I got this warning too, so I filed an issue to ask
>>> https://github.com/r-lib/roxygen2/issues/1654
>>>
>>> On Mon, Sep 2, 2024 at 2:58 PM John Fox <jfox using mcmaster.ca> wrote:
>>>>
>>>> As it turned out, I was able to avoid redefining coef.merMod(), 
>>>> etc., by
>>>> making a simple modification to the cv package.
>>>>
>>>> I'm still curious about whether it's OK to have unregistered S3 methods
>>>> for internal use in a package even though that's no longer necessary 
>>>> for
>>>> the cv package.
>>>>
>>>> On 2024-09-02 11:34 a.m., John Fox wrote:
>>>>> Caution: External email.
>>>>>
>>>>>
>>>>> Dear R-package-devel list members,
>>>>>
>>>>> I want to introduce several unregistered S3 methods into the cv 
>>>>> package
>>>>> (code at <https://github.com/gmonette/cv>). These methods have the 
>>>>> form
>>>>>
>>>>>          coef.merMod <- function(object, ...) lme4::fixef(object)
>>>>>
>>>>> The object is to mask, e.g., lme4:::coef.merMod(), which returns BLUPs
>>>>> rather than fixed effects, internally in the cv package but *not* to
>>>>> mask the lme4 version of the method for users of the cv package -- 
>>>>> that
>>>>> could wreak havoc with their work. Doing this substantially simplifies
>>>>> some of the code in the cv package.
>>>>>
>>>>> My question: Is it legitimate to define a method in a package for
>>>>> internal use without registering it?
>>>>>
>>>>> This approach appears to work fine, and R CMD check doesn't complain,
>>>>> although Roxygen does complain that the method isn't "exported"
>>>>> (actually, isn't registered).
>>>>>
>>>>> Any advice or relevant information would be appreciated.
>>>>>
>>>>> Thank you,
>>>>>    John
>>>>> -- 
>>>>> John Fox, Professor Emeritus
>>>>> McMaster University
>>>>> Hamilton, Ontario, Canada
>>>>> web: https://www.john-fox.ca/
>>>>> -- 
>>>>>
>>>>> ______________________________________________
>>>>> 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
>>>
>>> ______________________________________________
>>> R-package-devel using r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>
>> -- 
>> Sent from my phone. Please excuse my brevity.
> 
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel


More information about the R-package-devel mailing list