From jmc at r-project.org  Sun May 15 20:33:43 2011
From: jmc at r-project.org (John Chambers)
Date: Sun, 15 May 2011 11:33:43 -0700
Subject: [Rd] By default, `names<-` alters S4 objects
In-Reply-To: <4DCF0676.5070407@fhcrc.org>
References: <4DCF0676.5070407@fhcrc.org>
Message-ID: <4DD01C87.8040202@r-project.org>

This is basically a case of a user error that is not being caught:

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.

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 ....)

Comments?

John


>
> Thanks,
> H.
>
>



[Rd] By default, `names<-` alters S4 objects
John Chambers