[Rd] New relations between S3, S4 classes (was: Re: '"ts" treated as a registered S3 class ...)

John Chambers jmc at r-project.org
Sun Sep 7 17:10:50 CEST 2008


This specific bug led to a much more general enhancement (which is what 
one hopes will happen occasionally from bug reports).  Changes to 
version 2.8.0 (r-devel) were committed today that fix the bug reported 
below, via the general changes.

General problem:  For "ts" and some other S3 classes, one would like to 
assert some S4 behavior (slot classes and/or inheritance) along with the 
S3 inheritance via setOldClass().

The solution is to allow an S4 class definition to be supplied to 
setOldClass(), along with the Classes argument to give the inheritance.  
See ?setOldClass and the new material in the NEWS file.

Classes "ts", "mts", and "data.frame" have revised S4 definitions using 
this feature.  (Any other candidates?  The requirement is that one 
_really_ can assert that the S3 class has known attributes of known 
class and/or that all the code behaves correctly as if the class 
inherited from a virtual class, such as "structure".  Not that often 
that such assertions reliably apply to S3 classes.)

A slightly related enhancement to setOldClass has been introduced at the 
same time.  The created S4 class now has the S3 inheritance coded 
complete in the prototype of the S4 class.  This means that mutiple S3 
classes sharing the same inheritance can be declared to setOldClass() by 
just giving the first class they inherit from--the rest of the 
inheritance will be filled in automatically.  (Only relevant if you have 
S3 classes with a fairly deep inheritance structrue.)

A new technique using the information is to "fill in" the S3 inheritance 
by a special mechanism:
  as(x, "S3")
where x is an S3 object with perhaps just a single S3 class in its class 
attribute.  The object returned will have filled in the inheritance, S3 
style, if the classes involved have been registered by setOldClass().  
See ?S3




John Chambers wrote:
> Yohan Chalabi wrote:
>> Dear all,
>>
>> In R-devel I have noticed the new approach for the "ts" class in the
>> package "methods".
>>
>> the "structure" behaviour of "ts" is not always kept when one uses
>> "ts" objects and objects of classes which extend the virtual class
>> "structure".
>>
>> As a short example:
>>
>> ## this works fine
>> setClass("foo", representation(header = "character"), contains = 
>> "structure")
>> foo <- new("foo", 1:10, header = "foo")
>> ts <- ts(1:10)
>> foo / ts
>>
>> ## but the problem appears when one defines an "Ops" method for class 
>> "foo"
>> setMethod("Ops", c("foo", "foo"),
>>            function(e1, e2) {
>>                .Data <- callGeneric(e1 at .Data, e2 at .Data)
>>                header <- paste(e1 at header, e2 at header, sep = "_")
>>                new("foo", .Data, header = header)
>>            })
>> foo <- new("foo", 1:10, header = "foo")
>> foo + foo
>> ts <- ts(1:10)
>> foo / ts
>> # Error in getDataPart(1:10) : no '.Data' slot defined for class "ts"
>>
>> Is this the expected behavior?
>>   
> No, not expected.  It may take some special treatement to fix it, though.
>
> Your subject heading is indeed the problem.  Normally, the structure 
> of an S3 class is a black box, and no S4 slots should usually be 
> associated with it when it's registered via setOldClass.
>
> However, just because "ts" does want to be a "structure" class, it 
> would be nice to give it a .Data slot.  I'll experiment with this and 
> see if it causes other things to break immediately.
>
> Thanks for the report.
>
> John Chambers
>> regards,
>> Yohan
>>
>> -- 
>> PhD student
>> Swiss Federal Institute of Technology
>> Zurich
>>
>> www.ethz.ch
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>



More information about the R-devel mailing list