Re: [Rd] S4 method dispatch

From: John Chambers <jmc_at_r-project.org>
Date: Sun, 18 Sep 2011 14:04:41 -0700

The distinction here is "simple inheritance" ("Software for Data Analysis", p. 346). Your first example is simple inheritance (would be clearer if you used the contains= argument). In the second version you supply an explicit coerce method, so method dispatch can no longer just pass in the object from the subclass, but has to call the coerce method explicitly. Details in the reference.

If you need to have an explicit coerce method, it's possible to emulate simple inheritance, but the programming may be more subtle than you want to take on. When your method is called, it actually gets also an argument strict= which will be FALSE for method dispatch. You need to take account of the strict= argument in writing your method. See ?setAs for a few more details. Someone on the list may have an example.

John

On 9/18/11 3:33 AM, Edzer Pebesma wrote:
> 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.
>



R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Sun 18 Sep 2011 - 21:10:40 GMT

This quarter's messages: by month, or sorted: [ by date ] [ by thread ] [ by subject ] [ by author ]

All messages

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Fri 30 Sep 2011 - 08:50:35 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.

list of date sections of archive