As a follow-up, I managed to isolate the problem I sent earlier this
week, and reduced it to a small case (I'm using R 2.13.1,
i486-pc-linux-gnu (32-bit)).
The following script does what I expect:
setClass("A", representation(x = "numeric"))
setClass("AB", representation("A"))
setGeneric("doNothing<-", function(obj, value)
standardGeneric("doNothing<-"))
setReplaceMethod("doNothing", c("A", "character"),
function(obj, value) obj)
x = new("AB", x = 10)
doNothing(x) = "irrelevant"
class(x)
setAs("AB", "A", function(from) new("A", x = from@x))
x = new("AB", x = 10)
doNothing(x) = "irrelevant"
class(x)
and results in class(x) being "AB".
However, the following, very similar script:
setClass("A", representation(x = "numeric"))
setClass("AB", representation("A"))
setGeneric("doNothing<-", function(obj, value)
standardGeneric("doNothing<-"))
setReplaceMethod("doNothing", c("A", "character"),
function(obj, value) obj)
setAs("AB", "A", function(from) new("A", x = from@x))
x = new("AB", x = 10)
doNothing(x) = "irrelevant"
class(x)
returns "A" as the class of x. Why is this the case? Is this behaviour
intentional?
Best regards,
On 09/14/2011 11:00 PM, Edzer Pebesma wrote:
List,
In order to get rid of some old, unreadable S3 code in package sp, I'm
trying to rewrite things using S4 methods. Somewhere I fail, and I
cannot sort out why. In order to isolate the problem, I created two
functions, doNothing<- and dosth, and both should do nothing. The issue
is that in most cases they do nothing, but in some cases dosth(obj)
changes the class of obj and breaks with the error. I couldn't find a
pattern when this happens, but have a few cases where it consistently
breaks. Here's the code snippet:
setGeneric("doNothing<-", function(object, value)
standardGeneric("doNothing<-"))
setReplaceMethod("doNothing",
signature(object = "Spatial", value = "ANY"),
function(object, value) object)
dosth = function(obj) {
cl1 = class(obj)
doNothing(obj) = TRUE
cl2 = class(obj)
if (!identical(cl1, cl2)) {
print(paste(cl1, cl2))
stopifnot(identical(cl1, cl2))
}
obj
}
When things go wrong, dosth and doNothing are called with a subclass of
Spatial, e.g. an object of class SpatialGrid, but when this gets in
doNothing, the object is suddenly of class Spatial, and is then
returned
as an object of class Spatial, which should never happen.
For instance, I have a case where consistently
setMethod("fullgrid", c("Spatial"),
function(obj) { is(obj, "SpatialGrid") })
class(g)
[1] "SpatialGrid"
attr(,"package")
[1] "sp"
fullgrid(g)
[1] FALSE
is obviously false, but in other cases it works fine.
When I change the signature of doNothing to signature(object = "ANY",
value = "ANY"), the problem disappears.
I tried to make a self-contained example that reproduced the issue, but
could only get something that worked as expected.
I would appreciate any help or suggestions.