From edzer.pebesma at uni-muenster.de  Sun Sep 18 12:33:09 2011
From: edzer.pebesma at uni-muenster.de (Edzer Pebesma)
Date: Sun, 18 Sep 2011 12:33:09 +0200
Subject: [Rd] S4 method dispatch
In-Reply-To: <4E7115F6.20209@uni-muenster.de>
References: <4E7115F6.20209@uni-muenster.de>
Message-ID: <4E75C8E5.4000607@uni-muenster.de>

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 at 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 at 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.

-- 
Edzer Pebesma
Institute for Geoinformatics (ifgi), University of M?nster
Weseler Stra?e 253, 48151 M?nster, Germany. Phone: +49 251
8333081, Fax: +49 251 8339763  http://ifgi.uni-muenster.de
http://www.52north.org/geostatistics      e.pebesma at wwu.de



[Rd] S4 method dispatch
Edzer Pebesma