Herve Pages wrote: > Hi, > > It doesn't seem that the dispatching algo is finding my coerce method under > some circumstances. > Let's say I have 2 classes, A and AA and that AA is just a direct extension > of A with no additional slots: > > setClass("A", representation(ii="integer")) > setClass("AA", contains="A") > > I can define a method for coercing my objects to an integer vector with: > > setAs("A", "integer", function(from) {cat("I'm the A->integer coerce > method\n"); [EMAIL PROTECTED]) > > and this works as expected when my object is an AA instance: > > > aa <- new("AA", ii=sample(10, 5)) > > as(aa, "integer") > I'm the A->integer coerce method > [1] 10 1 6 4 7 > > But things don't behave that way anymore if I introduce a direct extension of > AA: > > setClass("OrderedAA", > contains="AA", > validity=function(object) > { > if (!all(diff([EMAIL PROTECTED]) >= 0)) > return("slot 'ii' is not ordered") > TRUE > } > ) > > and a method for coercing an A object to an OrderedAA object: > > setAs("A", "OrderedAA", > function(from) > { > cat("I'm the A->OrderedAA coerce method\n") > new("OrderedAA", ii=sort([EMAIL PROTECTED])) > } > ) > > My A->OrderedAA coerce method is not called anymore: > > > oaa <- as(aa, "OrderedAA") > > oaa > > validObject(oaa) > Error in validObject(oaa) : > invalid class "OrderedAA" object: slot 'ii' is not ordered > > This looks like a bug to me. > Well, obscure perhaps, and not as well documented as it might be.
Defining a subclass of "AA" creates implicit coerce methods in both directions. The method from "AA" to its subclass creates a new object from the subclass, then inserts the inherited slots. > selectMethod("coerce", c("AA", "OrderedAA")) Method Definition: function (from, to) { obj <- new("OrderedAA") as(obj, "AA") <- from obj } Signatures: from to target "AA" "OrderedAA" defined "AA" "OrderedAA" The situation is made more confusing because these methods are only explicitly inserted in the coerce() function the first time they're used (for obvious efficiency reasons). Notice that this is a direct method, not an inherited one. It will be chosen by the method selection from as(). So it is true that if you want to override the implicit methods, you have to do that for each new subclass, presumably when defining the subclass. > setAs("AA", "OrderedAA", + function(from) + { + cat("I'm the A->OrderedAA coerce method\n") + new("OrderedAA", ii=sor .... [TRUNCATED] > as(aa, "OrderedAA") I'm the A->OrderedAA coerce method An object of class "OrderedAA" Slot "ii": [1] 4 5 7 8 10 It's possible to argue that an inherited, explicitly defined method, as in your case, is worth more than a direct, implicitly defined method. But whether this would be true in all applications is not obvious. But that the documentation needs to spell this out--no question. Thanks for bringing it up. John > Thanks, > H. > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel