From jmc at r-project.org  Thu Oct 18 21:03:49 2012
From: jmc at r-project.org (John Chambers)
Date: Thu, 18 Oct 2012 12:03:49 -0700
Subject: [Rd] S4 fails to initialize linear hierarchies with
 intermediate VIRTUAL classes
In-Reply-To: <508004C0.3010208@fhcrc.org>
References: <508004C0.3010208@fhcrc.org>
Message-ID: <50805295.2030302@r-project.org>



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



[Rd] S4 fails to initialize linear hierarchies with intermediate VIRTUAL classes
John Chambers