My impression (but just as a user, not an implementer) is that the
NAMESPACE mechanism is intended to search for anything, not just for
methods, as follows:
- look in the namespace itself;
- look in the imports, which are in the parent.env of the namespace;
- look in the base package's namespace.
Period. This provides a definition of the behavior of functions in the
package that is independent of the dynamically changing contents of the
search list.
But the catch, it seems, is that the third element above, the base
namespace, has the Global namespace as its parent. As a result, I
believe the search continues through the entire search list, when one is
using exists() or get() in the ordinary way.
The effect is only noticeable, of course, if the object in question is
_not_ found in the first three environments searched. As a result, it's
not widely obvious. But it does seem, in principle, to violate the
concept of the namespace.
The mechanisms in the methods package that do searching are intended to
use the three-part interpretation of namespaces above; just what if
anything in the changes between 2.7.0 and r-devel would cause the
different results isn't obvious, but if I understand your example, the
current behavior seems as intended.
"Depends" may cause the relevant packages to be put on the search
list.
But a subsequent attach or detach could change what objects were found.
So unless this is not the intended interpretation of namespaces, looking
in the search list seems a bad idea in principle.
Martin Morgan wrote:> My conception of how NAMESPACE and methods in R-2.7.0 resolved a
> generic 'func' to a func-method was to search as follows:
>
> In 2.7.0:
>
> func -->
> NAMESPACE, including Imports: (and other details) -->
> .GlobalEnv, and eventually Depends: since these are on search()
>
> In R-devel it seems like
>
> func -->
> NAMESPACE, including Imports: (and other details) -->
> ?? but not pkgs in Depends:
>
> Is this correct or as intended, or is there a better conception to
> have?
>
> This model is from the following:
>
> In 2.7.0:
>
>
>> library(KEGG.db) # Imports, Depends AnnotationDbi; KEGG.db is data-only
>> head(ls(KEGGPATHID2EXTID))
>>
> [1] "hsa00232" "hsa00230" "hsa04514"
"hsa04010" "hsa04012" "hsa04150"
>
> vs. in a package tmpA with a NAMESPACE with Depend: and Imports:
> KEGG.db and in a new session of R
>
>
>> library(tmpA)
>> dokegg
>>
> function ()
> {
> require("KEGG.db")
> head(ls(KEGGPATHID2EXTID))
> }
> <environment: namespace:tmpA>
>
>> dokegg()
>>
> [1] "hsa00232" "hsa00230" "hsa04514"
"hsa04010" "hsa04012" "hsa04150"
>
> In R-devel
>
>
>> dokegg()
>>
> Error in as.environment(pos) : invalid object for 'as.environment'
> Error in head(ls(KEGGPATHID2EXTID)) :
> error in evaluating the argument 'x' in selecting a method for
function 'head'
>
> In some ways this seems good (tmpA author has to specify use of
> AnnotationDbi::ls, and tmpA is not confused by things the user does to
> their environment) but in other ways it seems to undo any benefit of
> method dispatch and requires the tmpA author to fully discover (and
> monitor -- what if AnnotationDbi splits 'ls' into a AnnotationBase
> pkg?) the class hierarchy.
>
> The specific example of KEGG.db and AnnotationDbi is maybe more
> interesting than others, because there is really no functionality to
> be imported from KEGG.db.
>
> Martin
>
[[alternative HTML version deleted]]