On 7/5/06, Thomas Lumley <[EMAIL PROTECTED]> wrote: > On Wed, 5 Jul 2006, Gabor Grothendieck wrote: > > > On 7/5/06, Thomas Lumley <[EMAIL PROTECTED]> wrote: > >> On Wed, 5 Jul 2006, Gabor Grothendieck wrote: > >> > >> > On 7/5/06, Thomas Lumley <[EMAIL PROTECTED]> wrote: > >> >> On Tue, 4 Jul 2006, Gabor Grothendieck wrote: > >> >> > >> >> > In the code below, e is an environment which we copy to f and then > >> >> > add attributes to e. Now f winds up with the same attributes. > >> >> > > >> >> > In other words it seems that the attributes are a property of the > >> >> > environment itself and not of the variable. Thus it appears we > >> >> > cannot have two environment variables that correspond to the > >> >> > original environment but with different attributes. > >> >> > >> >> No, we can't. The two variables are references to the same environment, > >> so > >> >> they are the same. > >> >> > >> >> If you want the attributes to be copies rather than references then > >> create > >> >> a list with the environment as an element and put the attributes on the > >> >> list. > >> > > >> > I realize that that is how it works but what I was really wondering was > >> > should it work that way? > >> > > >> > >> I think it really should (and this question has come up before). If you > >> do > >> e<-environment() > >> f<-e > >> > >> then there is only one object that f and e both point to. Now, since such > >> things as S3 class and matrix dimension are implemented as attributes I > >> think you really have to consider the attributes as part of the object > >> [which is also how they are implemented, of course]. So if e and f are > >> the same object they should have the same attributes. > > > > I don't think this follows since in the other cases modifying the > > object also creates a copy. > > In cases other than environments, NULL, external pointers and weak > references a new object is (from the language definition point of view) > created on assignment. The fact that sometimes the actual memory > allocation is deferred is an implementation issue. > > That is > e <- 2 > f <- e > > creates two different vectors of length 1, so of course they can have > different attributes. > > For environments (and for NULL, external pointers, and weak references), > assignment does not create a new object. It creates another reference to > the same object. Since it is the same object, it is the same: attributes, > values, class, etc. > > > >> > >> Another reasonable position would be to disallow attributes on > >> environments (as we do with NULL, another reference object), but that > >> seems extreme. > > > > I don't think that that would solve it because there is still the issue > > of the class attribute which you can't disallow. > > Of course you can. It might be inconvenient, but it's not difficult. > > > > In fact consider this: > > > > e <- new.env() > > f <- e > > class(f) <- c("myenv", "environment") > > F <- function(x) UseMethod("F") > > F.environment <- function(x) 1 > > F.myenv <- function(x) 2 > > F(e) # 2 > > F(f) # 2 > > > > The point is that subclassing does not work properly with environments > > No, subclassing *does* work. f and e are the same object, so they have the > same class, c("myenv", "environment"). The thing that doesn't "work" the > way you expect is assignment: > f <- e > doesn't create a new object, as it would for any other sort of object. > > > yet subclasses of the environment class should be possible since R > > is supposed to be OO and I see no valid reason for exclusing environments > > for this. I guess in this discussion I am coming to the realization that > > this issue really is a problem with the current way R works. > > It really is the way R is designed to work. Whether it is a problem or not > is a separate issue. Environments really are references, not values, and > they really work differently from the way most other objects work.
Yes, it about how you *try* to look at it and not how it was designed. I was also bitten by this a few years ago. There are two ways to think of 'e' and 'f' above: 1) 'e' and 'f' are R objects (reference variables) that refers to a common object (the environment), and applying attr(e, name) <- value applies to the R reference object 'e' and attr(f, name) <- value applies to the 'f' object. 2) 'e' and 'f' are references to a common object (the environment) and attr(e, name) <- value applies to the common environment object and so do attr(f, name) <- value too. Case 1) is wrong and Case 2) is correct. If you prefer Case 1) you can wrap up your environment in a list, e.g. e <- list(env=new.env()) f <- list(env=e$env) This makes 'e' and 'f' two different object that can have different attributes, but both e$env and f$env refers to the same environment object. This is the basics of the Object class in the R.oo packages. Cheers Henrik > -thomas > > Thomas Lumley Assoc. Professor, Biostatistics > [EMAIL PROTECTED] University of Washington, Seattle > > ______________________________________________ > 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