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@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel