From murdoch at stats.uwo.ca  Thu Oct 30 16:03:53 2008
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Thu, 30 Oct 2008 11:03:53 -0400
Subject: [Rd] conditionally import a namespace?
In-Reply-To: <4909C84E.70800@stats.uwo.ca>
References: <94730b8a0810292340t7e328096u300e4a225e669c5d@mail.gmail.com>	<18697.49514.201691.329789@stat.math.ethz.ch>
	<4909C84E.70800@stats.uwo.ca>
Message-ID: <4909CCD9.2070500@stats.uwo.ca>

On 10/30/2008 10:44 AM, Duncan Murdoch wrote:
> On 10/30/2008 10:15 AM, Martin Maechler wrote:
>>>>>>> "FA" == Felix Andrews <felix at nfrac.org>
>>>>>>>     on Thu, 30 Oct 2008 17:40:17 +1100 writes:
>> 
>>     FA> Dear R-devel,
>>     FA> I have a problem defining the dependencies for a package.
>> 
>>     FA> My package (latticist, not yet released) "Suggests" RGtk2, but
>>     FA> specifically does not require it. If RGtk2 is available, the user can
>>     FA> call a function that builds a GUI with RGtk2. However, I do not want
>>     FA> to attach the RGtk2 namespace, because it is irrelevant to the user
>>     FA> and exports about 7500 symbols.
>> 
>>     FA> Last time I asked a similar question to this, Professor Ripley noted
>>     FA> that the usual method to get around this situation is the use an
>>     FA> explicit package prefix to function calls (the `::` operator). But
>>     FA> this is not so easy with non-standard functions. Take this chunk of
>>     FA> code:
>> 
>>     FA> widg <- gtkComboBoxEntryNewText()
>>     FA> widg$show()
>>     FA> widg["width-request"] <- 100
>> 
>>     FA> The first call is easy to prefix, as RGtk2::gtkComboBoxEntryNewText()
>>     FA> but the others, `$.RGtkObject` and `[<-.RGtkObject` are not.
>> 
>> indeed.
>> 
>>     FA> While I *could* rewrite all the code to use explicit functions, I
>>     FA> think, the resulting code would be much less clear.
>> 
>>     FA> Essentially what I want to do is conditionally import the RGtk2 namespace.
>>     FA> Any suggestions?
>> 
>> Maybe something along the line of
>> 
>> if(is.function(try(RGtk2::gtkComboBoxEntryNewText))) {
>>    library(RGtk2)
>>    ....
>>    ....
>> }
>> 
>> ??
> 
> I think the problem is that that puts the namespace on the user's search 
> list, which is what Felix wanted to avoid.  He would like to 
> import(RGtk2), but only if it exists.
> 
> There are conditionals allowed in NAMESPACE files, but I don't know if 
> they are allowed to be used to control imports.  They are not well 
> documented -- they were called "experimental" when introduced in 1.9.0.
> 
> If this is allowed, then something like
> 
> if( "RGtk2" %in% rownames(installed.packages()) ) {
>    import(RGtk2)
> }
> 
> should work.

I just did a little test, and it does appear to work if you use 
utils::installed.packages in the condition.  And one clarification: 
those lines go into your NAMESPACE file, not into R code.

Duncan Murdoch



[Rd] conditionally import a namespace?
Duncan Murdoch