[Rd] By default, `names<-` alters S4 objects
Hervé Pagès
hpages at fhcrc.org
Mon May 16 00:02:26 CEST 2011
On 11-05-15 11:33 AM, John Chambers wrote:
> This is basically a case of a user error that is not being caught:
Sure!
https://stat.ethz.ch/pipermail/r-devel/2009-March/052386.html
>
> On 5/14/11 3:47 PM, Hervé Pagès wrote:
>> Hi,
>>
>> I was stumped by this. The two S4 objects below looked exactly the same:
>>
>> > a1
>> An object of class "A"
>> Slot "aa":
>> integer(0)
>> > a2
>> An object of class "A"
>> Slot "aa":
>> integer(0)
>>
>> > str(a1)
>> Formal class 'A' [package ".GlobalEnv"] with 1 slots
>> ..@ aa: int(0)
>> > str(a2)
>> Formal class 'A' [package ".GlobalEnv"] with 1 slots
>> ..@ aa: int(0)
>>
>> But they were not identical:
>>
>> > identical(a1,a2)
>> [1] FALSE
>>
>> Then I found that one had a "names" attribute but not the other:
>>
>> > names(attributes(a1))
>> [1] "aa" "class" "names"
>> > names(attributes(a2))
>> [1] "aa" "class"
>>
>> > names(a1)
>> NULL
>> > names(a2)
>> NULL
>>
>> Which explained why they were not reported as identical.
>>
>> After tracking the history of 'a1', I found that it was created with
>> something like:
>>
>> > setClass("A", representation(aa="integer"))
>> [1] "A"
>> > a1 <- new("A")
>> > names(a1) <- "K"
>> > names(a1)
>> NULL
>>
>> So it seems that, by default (i.e. in the absence of a specialized
>> method), the `names<-` primitive is adding a "names" attribute to the
>> object. Could this behaviour be modified so it doesn't alter the object?
>
> Eh? But you did alter the object. Not only that, you altered it in what
> is technically an invalid way: Adding a names attribute to a class that
> has no names slot.
Ah, that's interesting. I didn't know I could put a names slot in my
class. Last time I tried was at least 3 years ago and that was causing
problems (don't remember the exact details) so I ended up using NAMES
instead. Trying again with R-2.14:
> setClass("A", representation(names="character"))
> a <- new("A")
> attributes(a)
$names
character(0)
$class
[1] "A"
attr(,"package")
[1] ".GlobalEnv"
> names(a)
NULL
> names(a) <- "K"
> attributes(a)
$names
[1] "K"
$class
[1] "A"
attr(,"package")
[1] ".GlobalEnv"
> names(a)
NULL
Surprise! But that's another story...
>
> The modification that would make sense would be to give you an error in
> the above code. Not a bad idea, but it's likely to generate more
> complaints in other contexts, particularly where people don't
> distinguish the "list" class from lists with names (the "namedList" class).
>
> A plausible strategy:
> 1. If the class has a vector data slot and no names slot, assign the
> names but with a warning.
>
> 2. Otherwise, throw an error.
>
> (I.e., I would prefer an error throughout, but discretion ....)
Or, at a minimum (if no consensus can be reached about the above
strategy), not add a "names" attribute set to NULL. My original
post was more about keeping the internal representation of objects
"normalized", in general, so identical() is more likely to be
meaningful.
Thanks,
H.
>
> Comments?
>
> John
>
>
>>
>> Thanks,
>> H.
>>
>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
--
Hervé Pagès
Program in Computational Biology
Division of Public Health Sciences
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N, M1-B514
P.O. Box 19024
Seattle, WA 98109-1024
E-mail: hpages at fhcrc.org
Phone: (206) 667-5791
Fax: (206) 667-1319
More information about the R-devel
mailing list