Peter Ruckdeschel
2007-May-21 06:57 UTC
[Rd] setIs-relation does not entail automatic coercion in S4 method dispatch --- should it?
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