> 1) renaming those methods (e.g., recover_data_foo, because as soon
as there is a something.foo
> in your namespace, it will be dispatched regardless of whether you
register it or not)
If I do that, then emmeans won't support foo objects until foopkg offers
the methods. My goal is to encourage package developers to replace my
existing methods but to support them until that is done.
> 2) register them dynamically on load time if foopkg is not
available.
Not necessary, as you already stated in (1). (But I do export a
'.emm_register()' function that makes it really easy for other package
developers to register their methods. It's based on similar code to what
you point to.)
Russ
-----Original Message-----
From: I?aki Ucar <iucar at fedoraproject.org>
Sent: Saturday, August 10, 2019 1:09 PM
To: Lenth, Russell V <russell-lenth at uiowa.edu>
Cc: r-package-devel at r-project.org
Subject: [External] Re: [R-pkg-devel] Farming out methods to other packages
On Sat, 10 Aug 2019 at 19:21, Lenth, Russell V <russell-lenth at uiowa.edu>
wrote:
Dear developers,
I maintain a package, emmeans, that provides post-hoc analyses for a
variety of models. These models are supported by writing S3 methods for
recover_data and emm_grid. Quite a few models are supported internally in
emmeans, but it would really be better if the packages that create model
objects would have their own implementations of these methods.
For example, a hypothetical package, foopkg may be used to fit a model,
thereby producing an object of class foo. Currently, emmeans has internal
functions recover_data.foo and emm_basis.foo (typically not exported). It
would be better if the developer of foopkg would incorporate and export her
own recover_data.foo and emm_basis.foo methods, so that those methods can
be modified as needed as foopkg is further developed. Once those methods
are incorporated in foopkg, then I would remove them from my next update of
emmeans. But while they are available in both places, the ones in foopkg
should be used.
The problem is that in the short term, recover_data.foo and
emm_basis.foo are still present in the namespace of emmeans. And I have
found in testing with a fake package that if the user codes, say,
emmeans::emmeans(model.foo, "treatment"), the methods internal to emmeans's
namespace are always used even when foopkg is attached and its recover_data
and emm_basis methods are registered. So the developer of foopkg can't even
test her own methods (except by changing the class name of the model
object).
What can be done to facilitate having another developer's methods to
override your own?
The order of dispatch is meant to ensure that your package can't be broken
by a clash with another one. In other words, if recover_data is called
inside emmeans, emmeans:::recover_data.foo is called, but then if it's
called inside foopkg, then foopkg:::recover_data.foo is called instead.
This feature, however, plays against your intended use case here, and I
think that the best way to circumvent it is by 1) renaming those methods
(e.g., recover_data_foo, because as soon as there is a something.foo in
your namespace, it will be dispatched regardless of whether you register it
or not), and 2) register them dynamically on load time if foopkg is not
available. There is an implementation for this available here:
https://github.com/r-lib/vctrs/blob/master/R/register-s3.R
I?aki