From hb at maths.lth.se  Tue Nov 23 22:17:29 2004
From: hb at maths.lth.se (Henrik Bengtsson)
Date: Tue Nov 23 22:17:42 2004
Subject: [Rd] str() resets class for environments
In-Reply-To: <Pine.LNX.4.61.0411231448350.27627@gannet.stats>
Message-ID: <002801c4d1a1$d7d46fa0$a20040d5@hblaptop>

> -----Original Message-----
> From: r-devel-bounces@stat.math.ethz.ch 
> [mailto:r-devel-bounces@stat.math.ethz.ch] On Behalf Of Prof 
> Brian Ripley
> Sent: Tuesday, November 23, 2004 4:22 PM
> To: Roger D. Peng
> Cc: R Devel
> Subject: Re: [Rd] str() resets class for environments
> 
> 
> On Tue, 23 Nov 2004, Roger D. Peng wrote:
> 
> > I noticed the following today --- str() seems to remove any extra 
> > class
> > information added to an environment.
> >
> >> e <- new.env()
> >> class(e)
> > [1] "environment"
> >> class(e) <- c("foo", class(e))
> >> class(e)
> > [1] "foo"         "environment"
> >> str(e)
> > Classes 'foo', 'environment' length 0 <environment>
> >> class(e)
> > [1] "environment"
> >
> > I'm not sure if this is related to the external pointer issue 
> > mentioned in
> > the NEWS file.
> 
> It is.  Needed essentially the same fix.
> 
> > Is this the intended behavior for environments?  (It happens
> > in today's R-devel also.)
> 
> I believe the intention is that you should not class 
> environments. Luke 
> suggested earlier that unclassing one be made an error, and I 
> have now 
> done that.  Note that environments are not copied, and so 
> everything you 
> do to one instance you do to all other instances of it.  
> Setting a class 
> makes little sense for such an object.

Neither should one set attributes on environment! See thread "The class
attribute on an environment seems buggy (PR#2159)" from October 14, 2002;
here https://stat.ethz.ch/pipermail/r-devel/2002-October/025197.html and
https://stat.ethz.ch/pipermail/r-devel/2002-October/025203.html. John
Chambers gave the following example and explanation:

"Any attribute of environments, not just the class, can be killed by
operating on the object "locally" in a function.

Example:

R> f <- function(x){ y <- x; attr(y, "foo") <- NULL; y}
R> ev <- new.env()
R> attr(ev, "foo") <- "bar"
R> ev
<environment: 0x8b515d4>
attr(,"foo")
[1] "bar"
R> f(ev)
<environment: 0x8b515d4>
R> ev
<environment: 0x8b515d4>

The reason is that the C routine `duplicate' does not duplicate an
environment  OR its attributes."

To extend an environment into new class, the solution is to wrap it up in an
object of another basic data type, for instance as an element in a list or
as an attribute to NA, and set the class on the latter instead. Example:

 object <- NA
 attr(object, ".env") <- new.env()
 class(object) <- "MyClass"

I do exactly this in my root class Object in the R.oo package. At the time,
I found accessing attributes to be a little bit faster than accessing
elements in list (plus NA objects are smaller than any other object).

Thus, I want to raise a warning on this, because after introducing the
"$.environment" and "$<-.environment" in R v1.9.1, the above problem is
likely to show up more frequently; it is really tempting and it may take
awhile before you detect problems. Should attr()<-, attributes()<-,
class()<- give an error when applied to an environment? I see no reason why
not.

Best wishes

Henrik

> 
> -- 
> Brian D. Ripley,                  ripley@stats.ox.ac.uk
> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
> University of Oxford,             Tel:  +44 1865 272861 (self)
> 1 South Parks Road,                     +44 1865 272866 (PA)
> Oxford OX1 3TG, UK                Fax:  +44 1865 272595
> 
> ______________________________________________
> R-devel@stat.math.ethz.ch mailing list 
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 
>


[Rd] str() resets class for environments
Henrik Bengtsson