[Rd] particulars of importing/loading libraries

Simon Urbanek simon.urbanek at r-project.org
Wed Jan 14 17:10:51 CET 2009


On Jan 14, 2009, at 10:52 , Sklyar, Oleg (London) wrote:

> Well, this is very reasonable and this is how it should be I would  
> say. If it was consistent, there would be no problem as they would  
> be easy to nail down. However, the problem is now that if I load  
> pack3 only (which imports pack2 only) then as.POSIXct exported from  
> pack1 is NOT available for functions in pack3,

Because pack3 didn't request it.


> but is available for calls from the global env (see example below).  
> It is obviously available for calls from functions in pack2 as there  
> it is imported directly. Although, why also testPosix() of pack2 is  
> then available for calls from the global env as it was only loaded  
> as import for pack3?
>

Global environment is not encapsulated - you have access to anything  
that has been attached - sort of implicitly importing anything that  
has even been [exported and] attached (there is really no concept of  
"importing" for the global environment, but the effect is analogous).  
This is a conceptual difference of the "interactive" use vs package  
code. Unlike package code you don't know in advance what you will be  
doing when you're working interactively, so I think it makes sense to  
assume that everything is implicitly imported.

Cheers,
S


> In my understanding if pack3 does not depend on pack1 directly,
> functionality of pack1 should not be available anywhere apart from
> functions called from pack2 as well as functions in pack2 should  
> only be
> available for calls by functions in pack3 but not in the global env...
> The semantics seems to be broken here, is it not?
>
>> library(pack3)
> Loading required package: pack2
> Loading required package: pack1
>> testPosix() ## from pack2
> [1] "2009-01-13 15:29:50 UTC"
> [1] "POSIXt"  "POSIXct"
> [1] "2009-01-13 15:29:50 UTC"
>> testPosix2()
> Error in as.POSIXct.default(testPosixVal) :
>  do not know how to convert 'testPosixVal' to class "POSIXlt"
>> as.POSIXct(pack1::testPosixVal)
> [1] "2009-01-13 15:29:50 UTC"
>
>
>
> Dr Oleg Sklyar
> Research Technologist
> AHL / Man Investments Ltd
> +44 (0)20 7144 3107
> osklyar at maninvestments.com
>
>> -----Original Message-----
>> From: Simon Urbanek [mailto:simon.urbanek at r-project.org]
>> Sent: 14 January 2009 15:38
>> To: Sklyar, Oleg (London)
>> Cc: r-devel at r-project.org
>> Subject: Re: [Rd] particulars of importing/loading libraries
>>
>>
>> On Jan 14, 2009, at 4:24 , Sklyar, Oleg (London) wrote:
>>
>>> Sorry Simon, you are right. I tried to recreate a problem
>> that I had
>>> with other packages where the packages were added to Depends but
>>> made a mistake. However the problem remains if I do the following.
>>>
>>> Added: pack1 to Depends of pack2. Now I create pack3 with the
>>> following contents: it does not import pack1 directly, nor depends
>>> on it. It rather imports pack2 and depends on pack2. I then expect
>>> the functionality of pack1 to be available still if I only
>> load pack3.
>>
>>
>> That is semantically not a reasonable requirement. pack3 cannot (and
>> should not) assume anything about the internals of pack2. If
>> it needs
>> a function from pack1, it has to import it from pack1. If pack2 re-
>> exported as.POSIXct then that would make it part of pack2's
>> interface
>> and then you're free to just depend on pack2.
>>
>> Cheers,
>> S
>>
>>
>>
>>> But I
>>> now get errors with pack3 calling the function from pack1. Does this
>>> mean I need to import and depend on pack1 and methods explicitly in
>>> pack3. I.e. do I have to import and depend on ALL the
>> packages that
>>> may
>>> be in use, even if they are imported by other that I depend on and
>>> import:
>>>
>>> ---- pack3: DESCRIPTION -----
>>>
>>> Package: pack3
>>> Version: 0.0.1
>>> Date: 12 Jan 2009
>>> Title: pack1 to test S3/S4 methods compatibility
>>> Author:  Oleg Sklyar
>>> Depends: R (>= 2.7.1), pack2
>>> Maintainer: Oleg Sklyar <osklyar at maninvestments.com>
>>> Description: pack3
>>> LazyLoad: yes
>>> License: Proprietary
>>> URL: http://www.maninvestments.com
>>> LazyLoad: no
>>>
>>> ---- pack3: NAMESPACE ------
>>> import(pack2)
>>> exportPattern("^[^\\.]")
>>>
>>> ---- pack3: posix.R ------
>>> testPosix2 = function() {
>>>   z = as.POSIXct(testPosixVal)
>>>   print(z)
>>>   print(class(z))
>>>   z
>>> }
>>>
>>> Note, that the above function is the same as in pack2, just a
>>> different
>>> name.
>>>
>>>
>>> *** R 2.9.0 (svn -r 46585)
>> [/share/research/R-devel/20081002/lib64/R]
>>> ***
>>>> library(pack3)
>>> Loading required package: pack2
>>> Loading required package: pack1
>>>> as.POSIXct(pack1::testPosixVal)
>>> [1] "2009-01-13 15:29:50 UTC"
>>>> testPosxi() ## called from pack2
>>> [1] "2009-01-13 15:29:50 UTC"
>>> [1] "POSIXt"  "POSIXct"
>>> [1] "2009-01-13 15:29:50 UTC"
>>>> testPosix2() ## called from pack3
>>> Error in as.POSIXct.default(testPosixVal) :
>>> do not know how to convert 'testPosixVal' to class "POSIXlt"
>>>
>>>
>>>
>>>
>>> Dr Oleg Sklyar
>>> Research Technologist
>>> AHL / Man Investments Ltd
>>> +44 (0)20 7144 3107
>>> osklyar at maninvestments.com
>>>
>>>> -----Original Message-----
>>>> From: Simon Urbanek [mailto:simon.urbanek at r-project.org]
>>>> Sent: 14 January 2009 01:51
>>>> To: Sklyar, Oleg (London)
>>>> Cc: r-devel at r-project.org
>>>> Subject: Re: [Rd] particulars of importing/loading libraries
>>>>
>>>> Oleg,
>>>>
>>>> On Jan 13, 2009, at 11:00 , Sklyar, Oleg (London) wrote:
>>>>
>>>>> Dear List:
>>>>>
>>>>> Sorry for posting maybe a trivial question, but I have a basic
>>>>> understanding problem. If I have say pack1 and pack2, two R
>>>> packages,
>>>>> and pack2 depends on and imports pack1 fully (as in the
>>>> code below),
>>>>> is
>>>>> there a way to make all the functionality of pack1
>> available for the
>>>>> global and other environments (not only for the functions
>>>> called from
>>>>> withing pack2) by loading pack2 only? I thought if pack2
>>>> depends on
>>>>> and
>>>>> imports pack1 and essentially reexports everything, one
>>>> should get the
>>>>> full functionality simply by loading pack2. This does not
>>>> seem to be
>>>>> the
>>>>> case or I am missing something trivial in my NAMESPACE/DESCRIPTION
>>>>> files?
>>>>>
>>>>> If this is documented in Writing R Extensions, I would be thankful
>>>>> for a
>>>>> page number and maybe a quick fix in my example below as so
>>>> far I have
>>>>> not been able to find a clear explanation.
>>>>>
>>>>> The problem can be illustrated by the following simple
>>>> example (this
>>>>> is
>>>>> a simple code for 2 packages, pack1 and pack2; plus an example).
>>>>>
>>>>
>>>> if you bothered to use R CMD check you would find your bug right
>>>> away:
>>>> * checking package dependencies ... ERROR
>>>> Namespace dependencies not required:
>>>>  pack1
>>>>
>>>> You simply forgot to add pack1 to the Depends: line - that's
>>>> all. Once
>>>> you fix that, you'll see what happens:
>>>>
>>>>> library(pack2)
>>>> Loading required package: pack1
>>>>> as.POSIXct(pack1::testPosixVal)
>>>> [1] "2009-01-14 01:38:08 UTC"
>>>>
>>>> Cheers,
>>>> S
>>>>
>>>>
>>>>> Thank you for your replies.
>>>>>
>>>>> Dr Oleg Sklyar
>>>>> Research Technologist
>>>>> AHL / Man Investments Ltd
>>>>> +44 (0)20 7144 3107
>>>>> osklyar at maninvestments.com
>>>>>
>>>>> --- pack1: DESCRIPTION ------
>>>>> Package: pack1
>>>>> Version: 0.0.1
>>>>> Date: 12 Jan 2009
>>>>> Title: pack1 to test S3/S4 methods compatibility
>>>>> Author:  Oleg Sklyar
>>>>> Depends: R (>= 2.7.1), methods
>>>>> Maintainer: Oleg Sklyar <osklyar at maninvestments.com>
>>>>> Description: pack1
>>>>> LazyLoad: yes
>>>>> License: Proprietary
>>>>> URL: http://www.maninvestments.com
>>>>> LazyLoad: no
>>>>>
>>>>> --- pack1: NAMESPACE ------
>>>>> import(methods)
>>>>> exportPattern("^[^\\.]")
>>>>> exportClasses(posixTime)
>>>>> exportMethods(as.POSIXct)
>>>>>
>>>>> --- pack1: posix.R ------
>>>>> setClass("posixTime", "numeric")
>>>>>
>>>>> setGeneric("as.POSIXct")
>>>>> setMethod("as.POSIXct", signature(x="posixTime"),
>>>>>  function(x, tz) {
>>>>>      z = x at .Data
>>>>>      attr(z,"class") = c("POSIXt", "POSIXct")
>>>>>      attr(z,"tzone") = "UTC"
>>>>>      z
>>>>>  }
>>>>> )
>>>>>
>>>>> testPosixVal = new("posixTime", as.numeric(Sys.time()))
>>>>>
>>>>> --- pack2: DESCRIPTION
>>>>> Package: pack2
>>>>> Version: 0.0.1
>>>>> Date: 12 Jan 2009
>>>>> Title: pack2 to test S3/S4 methods compatibility
>>>>> Author:  Oleg Sklyar
>>>>> Depends: R (>= 2.7.1), methods
>>>>> Maintainer: Oleg Sklyar <osklyar at maninvestments.com>
>>>>> Description: pack2
>>>>> LazyLoad: yes
>>>>> License: Proprietary
>>>>> URL: http://www.maninvestments.com
>>>>> LazyLoad: no
>>>>>
>>>>> --- pack2: NAMESPACE ------
>>>>> import(pack1)
>>>>> exportPattern("^[^\\.]")
>>>>>
>>>>> --- pack2: posix.R ------
>>>>> testPosix = function() {
>>>>>  z = as.POSIXct(testPosixVal)
>>>>>  print(z)
>>>>>  print(class(z))
>>>>>  z
>>>>> }
>>>>>
>>>>> ------ test code to run from global env, showing problems -------
>>>>> require(pack2)
>>>>>
>>>>> ## use as.POSIXct imported into pack2 from pack1 to do the
>>>>> conversion in
>>>>> the fun
>>>>> testPosix()
>>>>> #~ [1] "2009-01-13 15:29:50 UTC"
>>>>> #~ [1] "POSIXt"  "POSIXct"
>>>>> #~ [1] "2009-01-13 15:29:50 UTC"
>>>>>
>>>>> ## now try using it directly from the global env (pack1 was not
>>>>> explicitly loaded)
>>>>> as.POSIXct(pack1::testPosixVal)
>>>>> #~ Error in as.POSIXct.default(pack1::testPosixVal) :
>>>>> #~  do not know how to convert 'pack1::testPosixVal' to class
>>>>> "POSIXlt"
>>>>>
>>>>> ## now require pack1 explicitly and try again
>>>>> require(pack1)
>>>>> as.POSIXct(pack1::testPosixVal)
>>>>> #~ [1] "2009-01-13 15:29:50 UTC"
>>>>>
>>>>>
>>>>>
>>>>
>> **********************************************************************
>>>>> Please consider the environment before printing this email or its
>>>>> attachments.
>>>>> The contents of this email are for the named addressees
>>>> ...{{dropped:
>>>>> 19}}
>>>>>
>>>>> ______________________________________________
>>>>> R-devel at r-project.org mailing list
>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>> **********************************************************************
>>> Please consider the environment before printing this email or its
>>> attachments.
>>> The contents of this email are for the named addressees only.  It
>>> contains information which may be confidential and privileged.  If
>>> you are not the intended recipient, please notify the sender
>>> immediately, destroy this email and any attachments and do not
>>> otherwise disclose or use them. Email transmission is not a secure
>>> method of communication and Man Investments cannot accept
>>> responsibility for the completeness or accuracy of this
>> email or any
>>> attachments. Whilst Man Investments makes every effort to keep its
>>> network free from viruses, it does not accept
>> responsibility for any
>>> computer virus which might be transferred by way of this email or
>>> any attachments. This email does not constitute a request, offer,
>>> recommendation or solicitation of any kind to buy, subscribe, sell
>>> or redeem any investment instruments or to perform other such
>>> transactions of any kind. Man Investments reserves the right to
>>> monitor, record and retain all electronic communications
>> through its
>>> network to ensure the integrity of its systems, for record keeping
>>> and regulatory purposes.
>>> Visit us at: www.maninvestments.com
>>> TG0908
>>>
>> **********************************************************************
>>>
>>>
>>
>>
>
>



More information about the R-devel mailing list