From luke at stat.uiowa.edu  Sat Oct 30 18:16:33 2004
From: luke at stat.uiowa.edu (Luke Tierney)
Date: Sat Oct 30 18:16:40 2004
Subject: [Rd] Destructive str(...)?
In-Reply-To: <Pine.LNX.4.44.0410300859130.4649-100000@gannet.stats>
References: <Pine.LNX.4.44.0410300859130.4649-100000@gannet.stats>
Message-ID: <Pine.LNX.4.61.0410301104170.5261@itasca2.stat.uiowa.edu>

On Sat, 30 Oct 2004, Prof Brian Ripley wrote:

> On Fri, 29 Oct 2004, Simon Urbanek wrote:
>
>> I have encountered a strange behavior of the str function - it seems to
>> modify the object that is displayed. Probably I'm using something
>> unsupported (objects consisting just of an external reference), but
>
> Yes, and I think it is documented somewhere, but I can't lay my hands on
> it right now.
>
>> still I'm curious as of why this happens. I create (in C code)
>> EXTPTRSXP and associate a class to it via SET_CLASS. Such objects works
>> fine until it's passed to str as the following output demonstrates:
>>
>> > c<-.MCall("RController","getRController")
>> > c
>> [1] "<RController: 0x3be5d0>"
>> > str(c)
>> Class 'ObjCid' length 1 <pointer: 0x3be5d0>
>> > c
>> <pointer: 0x3be5d0>
>> > str(c)
>> length 1 <pointer: 0x3be5d0>
>>
>> The .MCall basically produces an external reference and assigns a class
>> (ObjCid) to it. There's a corresponding print method and it works fine.
>> However, when str is called, it strips the class information from the
>> object as a repeated call to str also shows:
>>
>>  > str(c); str(c)
>> Class 'ObjCid' length 1 <pointer: 0x3be5d0>
>> length 1 <pointer: 0x3be5d0>
>>
>> Is this behavior intentional, undocumented or simply wrong?
>
> The issue is almost certainly that something has forgotten/decided not to
> either set or respect SET_NAMED on the object, so when str does
>
> 	object <- unclass(object)
>
> or some such, the original object gets changed.  Now the `something' has
> to be C code: possibly yours but probably something in R itself.
>
> I think this is intentional.  External references do not get copied, and
> the advice I recall is to wrap them in a list for use at R level (and
> before setting a class on them).  In RODBC I took another tack, and attach
> the reference as an attribute to a `documentation' object.
>
> str() probably ought to be more cautious when it encounters at external
> reference or similar exotic object, since it will look at list elements
> and attributes.

It's probably just unclass itself, not an issue with NAMED. External
references are one of a handful of objects that are handled as
references to mutable objects rather than as immutable values (the
main other one being environments).  unclass is destructive when
applied to a reference object.  At some point it might make sense to
make unclass signal an error when used on a reference object, and
clean up the things this breaks, including str and a number of other
print methods.  On the other hand, the same issue exists with all
attributes on referece objects, so the safest approach is to use a
wrapper as Brian suggests.

luke

-- 
Luke Tierney
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:      luke@stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu


[Rd] Destructive str(...)?
Luke Tierney