I agree that require makes it clearer what happens, so I will probably change. The disadvantage is the (for some users confusing) messages/warnings if the package is not installed. Wrapping it in with suppressWarnings and suppressMessages before reprinting the load message solves that though:

if (suppressMessages(suppressWarnings(require(pkg1)))) {
 print("Loading required package: pkg1")
 ...
}

Thanks,
Jon

Henrik Bengtsson wrote:
if ("pkg1" %in% rownames(utils:::installed.packages()) ) {
  library(pkg1)
  ...
}

can be replaced by:

if (require("pkg1")) {
  ...
}

/Henrik

On Thu, Jul 2, 2009 at 5:29 AM, Jon Olav Skoien<j.sko...@geo.uu.nl> wrote:
Hi Seth,

And thanks for your suggestion! I was not able to do exactly what you
described (I have no earlier experience with using environments), but you
mentioning .onLoad was a good starting point. I have now removed all
references to pkg1 from the NAMESPACE, and wrote the following .onLoad
function:

.onLoad <- function(libname, pkgname) {
 if ("pkg1" %in% rownames(utils:::installed.packages()) ) {
  library(pkg1)
  info = matrix(c("fun1", "fun2", "fun3", rep("pkg2", 3), rep(NA,3)), ncol =
3)
  registerS3methods(info, package = "pkg1", env = environment(funInPkg2))
 }
}

New methods for functions fun1, fun2 and fun3 seem to be available if pkg1
is installed, while they are ignored if pkg1 is not installed. The function
above loads pkg1 automatically if installed (I would prefer this to be
optional), but at least it will not be necessary to download pkg1 (with all
its dependencies) for users without interest in it.

I have not found any description of registerS3methods (except from an old
.Rd file stating that it is not intended to be called directly), so there
might be better ways of doing this... And I am sure there is a better way of
assigning the right environment...

Thanks again,
Jon



Seth Falcon wrote:
Hi Jon,

* On 2009-06-30 at 15:27 +0200 Jon Olav Skoien wrote:

I work on two packages, pkg1 and pkg2 (in two different projects). pkg1
is quite generic, pkg2 tries to solve a particular problem within same field
(geostatistics). Therefore, there might be users who want to use pkg2 as an
add-on package to increase the functionality of pkg1. In other words,
functions in pkg1 are based on the S3 class system, and I want pkg2 to offer
methods for pkg2-objects to functions defined in pkg1, for users having both
packages installed. Merging the packages or making pkg2 always depend pkg1
would be the easiest solution, but it is not preferred as most users will
only be interested in one of the packages.

I'm not sure I understand the above, I think you may have a pkg2 where
you meant pkg1, but I'm not sure it matters.

I think the short version is, pkg2 can be used on its own but will do
more if pkg1 is available.  I don't think R's packaging system
currently supports conditional dependencies as you might like.
However, I think you can get the behavior you want by following a
recipe like:

* In pkg2 DESCRIPTION, list Suggests: pkg1.

* In pkg2 code, you might define a package-level environment and  in
.onLoad check to see if pkg1 is available.

    PKG_INFO <- new.env(parent=emptyenv())
    .onLoad <- function(libname, pkgname) {
        if (check if pkg1 is available) {
           PKG_INFO[["pkg1"]] <- TRUE
        }
    }

* Then your methods can check PKG_INFO[["pkg1"]].


    + seth

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel



______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to