Package developers,
I posted a question a couple of months ago dealing with how to reduce the number of dependencies in a package. Part of the specific issue I face is that I have a `cld` S3 method for which the generic is in the multcomp package, but I don't want to import multcomp because it comes with a number of unneeded dependencies.
My solution at first appeared to be that I could just export my function `cld.emmGrid`; then if users have the multcomp package, this method is available. I also moved multcomp from Imports to Suggests, so that it is no longer a dependency. This fix works just fine for me. It passed the preliminary CRAN checks and it was accepted by CRAN. But then I was advised that the package fails the CRAN checks with Debian because those checks require S3 methods to actually be registered.
So what I tried next is what Duncan Murdoch suggested earlier in this thread -- to register the method conditionally using the following code in my NAMESPACE:
if (requireNamespace("multcomp")) {
importFrom(multcomp, cld)
S3method(cld, emmGrid)
}
This worked fine in my initial testing, both with multcomp installed and with multcomp absent.
However, now the package doesn't pass the checking procedure. The reason apparently is that every package mentioned in import() or importFrom() -- conditionally or not -- must be listed in Imports in the DESCRIPTION file. I could move multcomp back to Imports, but that defeats the whole purpose of getting rid of unneeded dependencies. It's a Catch-22.
Is there any recourse possible? Alas, I'm guessing there isn't, unless we can convince everybody to allow unregistered S3 methods on all platforms. This situation makes it really difficult for package developers to provide methods for other contributors' packages and still keep theirs lightweight. Almost all S3 generics are very simple functions, so being forced to load a dozen or so namespaces just to register a method is crazy. Plus, the more dependencies a package has, the less robust it is to other developers' updates.
I'm now wondering how much interest there is in developing a separate package just for generics, say, "S3generics". We could all collaborate to contribute our own generics to that one package, move them out of our own packages, and instead import just that package.
Russ
Russell V. Lenth? -? Professor Emeritus
Department of Statistics and Actuarial Science??
The University of Iowa ?-? Iowa City, IA 52242? USA??
Voice (319)335-0712 (Dept. office)? -? FAX (319)335-3017
[R-pkg-devel] More on explosive dependencies
3 messages · Lenth, Russell V, David Hugh-Jones, Iñaki Ucar
Hi Russ, Possibly relevant: the modelgenerics package (on GitHub) does exactly what you're suggesting for standard model functions like `nobs` etc. I think at some point it is going to become part of the tidyverse. D On Mon, 16 Jul 2018 at 02:24, Lenth, Russell V <russell-lenth at uiowa.edu> wrote:
Package developers,
I posted a question a couple of months ago dealing with how to reduce the
number of dependencies in a package. Part of the specific issue I face is
that I have a `cld` S3 method for which the generic is in the multcomp
package, but I don't want to import multcomp because it comes with a number
of unneeded dependencies.
My solution at first appeared to be that I could just export my function
`cld.emmGrid`; then if users have the multcomp package, this method is
available. I also moved multcomp from Imports to Suggests, so that it is no
longer a dependency. This fix works just fine for me. It passed the
preliminary CRAN checks and it was accepted by CRAN. But then I was advised
that the package fails the CRAN checks with Debian because those checks
require S3 methods to actually be registered.
So what I tried next is what Duncan Murdoch suggested earlier in this
thread -- to register the method conditionally using the following code in
my NAMESPACE:
if (requireNamespace("multcomp")) {
importFrom(multcomp, cld)
S3method(cld, emmGrid)
}
This worked fine in my initial testing, both with multcomp installed and
with multcomp absent.
However, now the package doesn't pass the checking procedure. The reason
apparently is that every package mentioned in import() or importFrom() --
conditionally or not -- must be listed in Imports in the DESCRIPTION file.
I could move multcomp back to Imports, but that defeats the whole purpose
of getting rid of unneeded dependencies. It's a Catch-22.
Is there any recourse possible? Alas, I'm guessing there isn't, unless we
can convince everybody to allow unregistered S3 methods on all platforms.
This situation makes it really difficult for package developers to provide
methods for other contributors' packages and still keep theirs lightweight.
Almost all S3 generics are very simple functions, so being forced to load a
dozen or so namespaces just to register a method is crazy. Plus, the more
dependencies a package has, the less robust it is to other developers'
updates.
I'm now wondering how much interest there is in developing a separate
package just for generics, say, "S3generics". We could all collaborate to
contribute our own generics to that one package, move them out of our own
packages, and instead import just that package.
Russ
Russell V. Lenth - Professor Emeritus
Department of Statistics and Actuarial Science
The University of Iowa - Iowa City, IA 52242 USA
Voice (319)335-0712 (Dept. office) - FAX (319)335-3017
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Sent from Gmail Mobile [[alternative HTML version deleted]]
El lun., 16 jul. 2018 a las 3:24, Lenth, Russell V (<russell-lenth at uiowa.edu>) escribi?:
Package developers, I posted a question a couple of months ago dealing with how to reduce the number of dependencies in a package. Part of the specific issue I face is that I have a `cld` S3 method for which the generic is in the multcomp package, but I don't want to import multcomp because it comes with a number of unneeded dependencies. My solution at first appeared to be that I could just export my function `cld.emmGrid`; then if users have the multcomp package, this method is available. I also moved multcomp from Imports to Suggests, so that it is no longer a dependency. This fix works just fine for me. It passed the preliminary CRAN checks and it was accepted by CRAN. But then I was advised that the package fails the CRAN checks with Debian because those checks require S3 methods to actually be registered.
Is it *official* that the export() workaround won't work in future R versions? I'm using this in at least one package and it's not failing on those platforms.
So what I tried next is what Duncan Murdoch suggested earlier in this thread -- to register the method conditionally using the following code in my NAMESPACE:
if (requireNamespace("multcomp")) {
importFrom(multcomp, cld)
S3method(cld, emmGrid)
}
This worked fine in my initial testing, both with multcomp installed and with multcomp absent.
However, now the package doesn't pass the checking procedure. The reason apparently is that every package mentioned in import() or importFrom() -- conditionally or not -- must be listed in Imports in the DESCRIPTION file. I could move multcomp back to Imports, but that defeats the whole purpose of getting rid of unneeded dependencies. It's a Catch-22.
Is there any recourse possible? Alas, I'm guessing there isn't, unless we can convince everybody to allow unregistered S3 methods on all platforms. This situation makes it really difficult for package developers to provide methods for other contributors' packages and still keep theirs lightweight. Almost all S3 generics are very simple functions, so being forced to load a dozen or so namespaces just to register a method is crazy. Plus, the more dependencies a package has, the less robust it is to other developers' updates.
There is, actually: *dynamic registration*. It's based on calling registerS3method when the other package is loaded. This is done by calling setHook (in this case, on the multcomp "onLoad" event) from your package's .onLoad function. See the mechanism here: - Call register_s3_method in .onLoad if requireNamespace returns true (the package is available): https://github.com/tidyverse/googledrive/blob/master/R/aaa.R#L45 - The definition of register_s3_method, which calls registerS3method: https://github.com/tidyverse/googledrive/blob/master/R/dplyr-compat.R#L5 It seems that this mechanism will be added to roxygen2, according to https://github.com/klutometis/roxygen/issues/623, to avoid copying this code over from package to package. I?aki
I'm now wondering how much interest there is in developing a separate package just for generics, say, "S3generics". We could all collaborate to contribute our own generics to that one package, move them out of our own packages, and instead import just that package. Russ Russell V. Lenth - Professor Emeritus Department of Statistics and Actuarial Science The University of Iowa - Iowa City, IA 52242 USA Voice (319)335-0712 (Dept. office) - FAX (319)335-3017
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel