Use ::: or export everything when developing multi

2019-05-05 17:15发布

问题:

I am working on a family of R packages, all of which share substantial common code which is housed in an internal package, lets call it myPackageUtilities. So I have several packages

myPackage1, myPackage2, etc...

All of these packages depend on every method in myPackageUtilities. For a real-world example, please see statnet on CRAN. Each dependent package, of course, has

Depends: myPackageUtilities

in its DESCRIPTION file.

My question is: In the R code for myPackage1, which of the following two techniques for accessing methods from myPackageUtilities is preferable:

  1. Use ::: to access the methods in myPackageUtilities, or
  2. Export everything from myPackageUtilities (e.g. by including exportPattern("^[^\\.]") in the NAMESPACE)?

Option 2 clutters the end-user's search path, but the R gurus recommend against using :::.

Follow-up question: If (2) is the better choice, is there a way to export everything using roxygen2?

回答1:

Suppose we have a package called randomUtils and this package has a function called sd that calculates the Slytherin Defiance Quotient.

Now I write a package called spellbound. If spellbound Depends on randomUtils, then randomUtils::sd will be found in the search path and can conflict with calculating standard deviation.

If spellbound Imports randomUtils, however, then R will install randomUtils but will not load it when spellbound is loaded. Thus, the new version of sd can't be found on the search path, but can still be accessed by randomUtils::sd

With an ever growing body of contributed work on CRAN, it is becoming very important that we use Imports as much as possible so that we don't introduce unexpected behaviors by having conflicting function definitions.

An example of when I have used Depends: when writing the HydeNet package, I wanted the end user to be able to use the rjags package in concert with HydeNet. So I put rjags in Depends so that library (HydeNet) would loaf both packages. (In other words, put rjags on the search path.

Moral of the story, if you don't intend for the user to directly access the functions, it should go in Imports.