[Rd] setIs-relation does not entail automatic coercion in S4 method dispatch --- should it?

Peter Ruckdeschel Peter.Ruckdeschel at uni-bayreuth.de
Mon May 21 08:57:28 CEST 2007


Hi R-devels,

I am a bit puzzled about when/if "setIs-conditional" coercion is performed
in S4 method dispatch.

Setup: Myclass1 setIs()-conditionally is inheriting from Myclass2.

My first guess would have been:

If the corresponding test clause in setIs() is TRUE and there is
no Myclass1-method foo() but a Myclass2-method foo(), a call to
foo() with a corresponding Myclass1 instance as argument
automatically coerce this instance to Myclass2 using the coerce
function in setIs(). It does not; (consider the example below).

I am pretty sure that there are good reasons for this behaviour, but could you
give me arguments why this automatic coercion should not be a good idea?

###############################################################################
###### Begin of example
###############################################################################

setClass("Myclass1",representation(a="numeric"))
setClass("Myclass2",representation(b="numeric"))

### conditional inheritance by setIs

setIs("Myclass1", "Myclass2", test = function(obj) obj at a>0,
       coerce = function(obj) {cat("setIs coercion used\n")## does not seem to be used for
                               new("Myclass2", b=obj at a)   },  ## automatic coercion

       replace = function(obj, value) {cat("setIs replacement used\n") ## does not seem to be used...
                                       new("Myclass2", b=value at b)
                                      })

### accessor to slot b

if(!isGeneric("b")) setGeneric("b", function(object) standardGeneric("b"))
setMethod("b","Myclass2", function(object) object at b)

### a method for Myclass2
if(!isGeneric("foo")) setGeneric("foo", function(object) standardGeneric("foo"))
setMethod("foo","Myclass2",function(object)cat("Myclass2-fct:",b(object),"\n"))

###############################################################################

selectMethod("foo","Myclass2")  ### does find foo-method for class Myclass2 as expected
selectMethod("foo","Myclass1")  ### does find foo-method for class Myclass2 as expected

## an instance of Myclass1

MyC1   <- new("Myclass1",a=2)
MyC1.0 <- new("Myclass1",a=-2)

### implicit coercion using setIs coerce function does not work as I would have expected:

foo(MyC1)   ### does not coerce MyC1 to Myclass2 although possible
foo(MyC1.0) ### as expected: does not coerce as not possible

### explicit coercion:

foo(as(MyC1,"Myclass2"))   ### works as expected: uses foo-method for class Myclass2
foo(as(MyC1.0,"Myclass2")) ### works as expected: error as not coercable

### way out?

setMethod("b","Myclass1", function(object)
                            if (object at a>0)
                                object at a
                            else
                                stop("not coercable to class Myclass2")
          )
####

foo(MyC1)   ### works as expected: uses foo-method for class Myclass2
foo(MyC1.0) ### works as expected: error as not coercable

###############################################################################
###### End of example
###############################################################################

Any suggestion appreciated
thanks already
Peter



More information about the R-devel mailing list