[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