Martin Morgan
2012-Oct-18 13:31 UTC
[Rd] S4 fails to initialize linear hierarchies with intermediate VIRTUAL classes
Initialization of this simple hierarchy A = setClass("A", representation(x="numeric")) setClass("B", contains=c("VIRTUAL", "A")) C = setClass("C", contains="B") fails (neat that setClass returns generators; I hadn't realized that before!) > C(A()) Error: evaluation nested too deeply: infinite recursion / options(expressions=)? because in the default coerce<-,C,A-method > selectMethod("coerce<-", c("C", "A")) Method Definition: function (from, to = "A", value) { .value <- as(from, "B", TRUE) as(.value, "A") <- value ... as(from, "B", TRUE) correctly returns an instance of C. Also VIRTUAL isn't mentioned on ?Classes or ?setClass and isn't documented on class?VIRTUAL, making me wonder whether virtual classes are actually meant to be supported as part of S4 (they are used regularly in Bioconductor packages)? Martin -- Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793
John Chambers
2012-Oct-18 19:03 UTC
[Rd] S4 fails to initialize linear hierarchies with intermediate VIRTUAL classes
On 10/18/12 6:31 AM, Martin Morgan wrote:> Initialization of this simple hierarchy > > A = setClass("A", representation(x="numeric")) > setClass("B", contains=c("VIRTUAL", "A")) > C = setClass("C", contains="B") > > fails (neat that setClass returns generators; I hadn't realized that > before!)Yes, from 2.15.0. See ?setClass and the NEWS file.> > > C(A()) > Error: evaluation nested too deeply: infinite recursion / > options(expressions=)? > > because in the default coerce<-,C,A-method > > > selectMethod("coerce<-", c("C", "A")) > Method Definition: > > function (from, to = "A", value) > { > .value <- as(from, "B", TRUE) > as(.value, "A") <- value > ... > > as(from, "B", TRUE) correctly returns an instance of C.Hmm, correct. Direct specification of the slots is fine, but supplying a superclass object fails as you show. A "harmless" solution to this may take some thinking (suggestions welcome). Not for 2.15.2 at any rate. A workaround is to define the inheritance relation directly. In this example: setIs("C", "A", coerce = function(from) new("A", x = from at x), replace = function(from, value) {from at x = value at x; from}) Or, if it's more natural, supply an initialize() method for "C" to intercept such arguments.> > Also VIRTUAL isn't mentioned on ?Classes or ?setClass and isn't > documented on class?VIRTUAL, making me wonder whether virtual classes > are actually meant to be supported as part of S4 (they are used > regularly in Bioconductor packages)?Eh?? Of course they are. E.g., section 9.4 of the Software for Data Analysis reference. In particular, page 353: "Any ordinary class definition can create a virtual class, by including the special class "VIRTUAL" in the contains= argument to setClass()." John> > Martin