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.
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
attributes of S4 objects
2 messages · Parlamis Franklin, John Chambers
1 day later
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