From j.skoien at geo.uu.nl  Fri Jul  3 10:32:05 2009
From: j.skoien at geo.uu.nl (Jon Olav Skoien)
Date: Fri, 03 Jul 2009 10:32:05 +0200
Subject: [Rd] Conditional dependency between packages
In-Reply-To: <59d7961d0907021541t4c1f229ew156cade7cb1d72fa@mail.gmail.com>
References: <4A4A12BB.6020504@geo.uu.nl> <20090701162315.GV2739@ziti.local>
	<4A4CA812.5070301@geo.uu.nl>
	<59d7961d0907021541t4c1f229ew156cade7cb1d72fa@mail.gmail.com>
Message-ID: <4A4DC205.8000002@geo.uu.nl>

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.skoien at 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 at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>



[Rd] Conditional dependency between packages
Jon Olav Skoien