Parlamis Franklin wrote:> I am having a bit of a struggle deciding when to use attributes with
> S4 objects. Clearly the 'class' attribute will always be present.
> But it is not clear to me whether the architects of the methods
> package intend that other attributes, such as 'names', will still
be
> used when the S4 implementation is complete.
>
"Can of worms" might be a good description of this situation.
The cautious approach would be to not assume attributes get carried over
to an object that uses a basic R data type ("numeric" in your example)
as the data in the new class. If you need arbitrary attributes, it's
safer to make the old-style object into a slot:
setClass("Numeric", representation(x = "numeric"))
which should not balk at the slot having attributes.
Here's the underlying point: There are two very different computing
models here. Old-style attributes were basically undisciplined; each
object could have its own collection of attributes and these could
appear and disappear. Names are a good example:
> z = 1:10
> names(z) <- letters[1:10]
> names(attributes(z))
[1] "names"
> names(z) <- NULL
> names(attributes(z))
NULL
In contrast, S4 class definitions guarantee what slots are available,
and that they inherit from specified classes. So if names() in the S3
sense were made a part of the S4 object, they could not just disappear
as in this example. But then it's doubtful that the great mound of code
that uses names in the S3 sense would still all work correctly for
objects from the S4 classes. So the safe approach is to keep the two
ideas separate.
There are many ways to bridge the gap; for example, by having an
initialize() method for the S4 class that takes attributes from an S3
object and copies them into slots in the S4 object, when the attributes
happen to be there.
> I notice that, when you create a formal object from an informal one
> with attributes, the attributes are (often) assigned to the formal
> object. For example,
>
> setClass("Numeric", representation("numeric"))
> vec <- 1:10
> names(vec) <- letters[1:10]
> comment(vec) <- "comment"
> Vec <- new("Numeric", vec)
> attributes(Vec) ## 'names' and 'comment' attributes are
assigned to
> the formal object
>
> But I also notice that, in the absence of an appropriate 'coerce'
> method, 'as( , superclass)' will return an object without
attributes
>
> as(Vec, "numeric") ## gives an unnamed vector of mode numeric
with no
> comment attribute
>
> Because of this, I have found myself writing methods for the sole
> purpose of preserving attributes when coercing between basic data
> types and formal classes that extend them. But the default methods
> for coercing to the basic data types clearly want attributes to be
> stripped (they do so explicitly when strict=TRUE (the default)). I
> am thinking that maybe it was always intended that non-class
> attributes would not be used with formal objects, and that instead
> analogous slots would appear in any formal objects that extend basic
> data types (like the Dim and Dimnames attributes in the 'Matrix'
> mother class from the Matrix package).
>
> Is that true? Are attributes un-S4? Any and all style advice or
> examples would be appreciated.
>
> Franklin Parlamis
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>