[Rd] as() creates invalid entries in methods list?
Seth Falcon
sfalcon at fhcrc.org
Mon Apr 16 01:51:39 CEST 2007
Hi,
We've observed rather strange behavior related to as(). When as() is
used to make a conversion to a super class, an invalid entry is
inserted into the table of methods.
> setClass("A", contains="list")
> get(".MTable", environment(coerce))[["list#A"]]
NULL
> as(list(), "A")
> get(".MTable", environment(coerce))[["list#A"]]
function (from, to)
{
obj <- new("A")
as(obj, "list") <- from
obj
}
<environment: namespace:methods>
Entries in .MTable should be MethodDefinition objects (or at least
that is what is usually there for methods defined via setAs). It
happens that if you try to load a package that has a NAMESPACE file
with a directive exportMethods(coerce) but no call to setAs then you
get an error:
library("hello")
Error in .mergeMethodsTable(generic, mtable, get(tname, envir = env), :
Invalid object in meta table of methods for "coerce", label "list#A", had class "function"
So I think there are two problems that might need fixes:
1. methods::as shouldn't create invalid entries. I've included a
patch (see below) that seems to help, but I'm not sure it is the
right fix. For example, there are two helper functions that create
coerce methods and perhaps a better fix is for both of these to be
modified to return MethodDefinition objects.
2. The name space code allows packages to have methods listed in
exportMethods directives even if no corresponding setMethod,
setGeneric, or setAs call appears in the R code. Ideally, a
warning or error would be raised in this case. I'm not sure such a
declaration should do any harm in theory, but in practice it seems
to trigger subtle bugs in the methods package.
+ seth
--- a/src/library/methods/R/as.R
+++ b/src/library/methods/R/as.R
@@ -37,9 +37,6 @@ as <-
test <- ext at test
asMethod <- .makeAsMethod(ext at coerce, ext at simple, Class, Clas
canCache <- (!is(test, "function")) || identical(body(test),
- if(canCache) { # make into method definition
- asMethod <- .asCoerceMethod(asMethod, sig, FALSE)
- }
}
}
if(is.null(asMethod) && extends(Class, thisClass)) {
@@ -54,6 +51,10 @@ as <-
fdef = coerceFun, mlist =
coerceMethods)
inherited <- TRUE
+ } else {
+ if(canCache) { # make into method definition
+ asMethod <- .asCoerceMethod(asMethod, sig, FALSE)
+ }
}
## cache in the coerce function's environment
if(canCache && !is.null(asMethod)) {
--
Seth Falcon | Computational Biology | Fred Hutchinson Cancer Research Center
http://bioconductor.org
More information about the R-devel
mailing list