From murdoch at stats.uwo.ca  Fri Oct  6 15:30:50 2006
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Fri, 06 Oct 2006 09:30:50 -0400
Subject: [Rd] operator :: and symbols not in the namespace of a package
 with	a namespace (PR#9279)
In-Reply-To: <20061006130505.A50374BEC2@slim.kubism.ku.dk>
References: <20061006130505.A50374BEC2@slim.kubism.ku.dk>
Message-ID: <45265A8A.6060505@stats.uwo.ca>

On 10/6/2006 9:05 AM, thomas.friedrichsmeier at rub.de wrote:
> Full_Name: Thomas Friedrichsmeier
> Version: 2.4.0
> OS: GNU/Linux
> Submission from: (NULL) (84.61.116.51)
> 
> 
> Since R 2.4.0, operator "::" also returns objects in the package environment, if
> the package does not have a namespace. This is a very welcome addition.
> 
> Additional wish:
> If a package has a namespace, but does not place all symbols in that namespace,
> lookup will still fail. For example in package boot (version 1.2-26):
> 
> library (boot)
> exists ("motor", envir=as.environment ("package:boot"))   # TRUE
> getAnywhere ("motor")                                     # found in
> package:boot
> boot::motor                                               # error not in
> namespace
> 
> This is as documented, but I think it would be convenient, if boot::motor would
> also return the object in this case.

At first I was ready to disagree with you, telling you to use the ":::" 
operator for something that is not exported:  but in fact motor is a 
dataset, so it is exported from the package by being loaded into the 
package environment when the package is loaded.  I agree that the "::" 
operator should find it.

I think the rule should be:  the "::" operator looks at the symbols that 
are publicly available from the package, i.e. boot::motor should 
effectively be an abbreviation for

get("motor", pos="package:boot", inherits=FALSE)

after making sure boot is loaded.  I think getExportedValue() is a much 
more rarely needed function, so users should need to use it explicitly.

Duncan Murdoch

> 
> This might be achieved by adding an additional tryCatch in "::": If the package
> has a namespace, try getExportedValue (), if that fails, try to get from package
> environment instead. E.g.:
> 
> "::" <- function (pkg, name)
> {
>     pkg <- as.character(substitute(pkg))
>     name <- as.character(substitute(name))
>     ns <- tryCatch(asNamespace(pkg), hasNoNamespaceError = function(e) NULL)
>     if (is.null(ns)) {
>         pos <- match(paste("package", pkg, sep = ":"), search(), 
>             0)
>         if (pos == 0) 
>             stop(gettextf(paste("package '%s' has no name space and", 
>                 "is not on the search path"), pkg), domain = NA)
>         get(name, pos = pos, inherits = FALSE)
>     }
>     else tryCatch(getExportedValue(pkg, name), error=function (e) {
>                        pos <- match(paste("package", pkg, sep=":"), search(),
> 0)
>                        get(name, pos, inherits=FALSE)
>                   })
> }
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel




[Rd] operator :: and symbols not in the namespace of a package with a namespace (PR#9279)
Duncan Murdoch