[R-pkg-devel] Unneeded S3 method registration

Duncan Murdoch murdoch@dunc@n @end|ng |rom gm@||@com
Thu May 11 10:58:17 CEST 2023


The problem is that there's no way to declare that an internal function 
should or shouldn't be treated as an S3 method, other than by declaring 
it as one in NAMESPACE and exporting it.  If you read the thread 
"Unfortunate function name generic.something​" that started last week, 
you'll see the opposing problem to yours:  a local function named 
levels.no that isn't intended to be an S3 method, but will be treated as 
one in some circumstances.

You do export emm_basis and recover_data, so those generics are 
available to users.  And you do declare some of the methods, e.g. in 
emmeans 1.8.5, users can see methods for some classes:

 > methods("emm_basis")
[1] emm_basis.aovlist* emm_basis.lm*      emm_basis.lme* 
emm_basis.merMod*  emm_basis.mlm*

As the message below says, you don't declare emm_basis.Gam to be a 
method, which means that a user with a Gam object who calls emm_basis 
will get the default method instead, whereas when code in your package 
calls it, they'll get the Gam method.

You say users should never call emm_basis directly, but package 
developers should provide methods for it.  At a minimum that's going to 
make debugging those packages much more confusing.  And if they have a 
class which inherits from Gam and want to call the inherited method, 
they won't get it.

So I think in this case the NOTE is something you should fix.

Duncan Murdoch

On 10/05/2023 10:49 p.m., Lenth, Russell V wrote:
> Dear R package developers
> 
> My emmeans package failed preliminary checks when I submitted an update today, apparently due to a recent change in requirements on method registration. The message I got was:
> 
> * checking S3 generic/method consistency ... NOTE
> Apparent methods for exported generics not registered:
>    emm_basis.Gam emm_basis.MCMCglmm emm_basis.averaging
>    emm_basis.betareg emm_basis.brmsfit emm_basis.carbayes emm_basis.clm
>    emm_basis.clmm emm_basis.coxme emm_basis.coxph emm_basis.default
>    emm_basis.gam emm_basis.gamlss emm_basis.gamm emm_basis.gee
>    emm_basis.geeglm emm_basis.geese emm_basis.gls emm_basis.gnls
>    emm_basis.hurdle emm_basis.lqm emm_basis.lqmm emm_basis.mblogit
>    emm_basis.mcmc emm_basis.mcmc.list emm_basis.mira emm_basis.mmer
>    emm_basis.multinom emm_basis.nlme emm_basis.nls emm_basis.polr
>    emm_basis.qdrg emm_basis.rms emm_basis.rq emm_basis.rqs
>    emm_basis.stanreg emm_basis.survreg emm_basis.svyolr
>    emm_basis.zeroinfl recover_data.MCMCglmm recover_data.averaging
>    recover_data.betareg recover_data.brmsfit recover_data.carbayes
>    recover_data.clm recover_data.clmm recover_data.coxme
>    recover_data.coxph recover_data.default recover_data.gam
>    recover_data.gamlss recover_data.gamm recover_data.gee
>    recover_data.geeglm recover_data.geese recover_data.gls
>    recover_data.gnls recover_data.hurdle recover_data.lqm
>    recover_data.lqmm recover_data.manova recover_data.mblogit
>    recover_data.mcmc recover_data.mcmc.list recover_data.mira
>    recover_data.mmer recover_data.multinom recover_data.nlme
>    recover_data.nls recover_data.polr recover_data.qdrg recover_data.rms
>    recover_data.rq recover_data.rqs recover_data.stanreg
>    recover_data.survreg recover_data.svyglm recover_data.svyolr
>    recover_data.zeroinfl
> See section 'Registering S3 methods' in the 'Writing R Extensions'
> manual.
> 
> I guess my question is "why does this matter?" There are many, many functions mentioned here, but they are all methods for emm_basis and recover_data. Both generics are in the emmeans namespace, as are all these functions.
> 
> The section on registering S3 methods explains:
> 
>> The standard method for S3-style UseMethod dispatching might fail to locate methods defined in a package that is imported but not attached to the search path. To ensure that these methods are available the packages defining the methods should ensure that the generics are imported and register the methods using S3method directives...
> 
> But clearly all those methods flagged in the messages will be found in the same namespace as the generics -- emm_basis and recover_data -- so not being able to find them is not an issue. Moreover, emm_basis() and recover_data() are not meant to be called directly by a user, or even by code in another package. They are only meant to be called within the function emmeans::ref_grid(), and the existence of those generics and methods is simply a mechanism for being able to support a lot of different model classes.
> 
> Obviously, I could add a whole lot of S3method() directives to the NAMESPACE file, but it just seems wasteful to export all those methods when they are never needed outside the emmeans namespace.
> 
> Am I missing something?
> 
> Thanks
> 
> Russ Lenth
> 
> 
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> 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