Aleksey Naumov
2000-Jun-13 19:47 UTC
[R] Question on closure (lexical scoping) and encapsulation
Dear R users, I have two related questions about scoping and data encapsulation. One is fairly specific - I am looking at "scoping.R" which is used in demo(scoping) - it's an example of lexical scoping and encapsulation. Where is the 'total' stored? It is not an attribute in 'ross' or 'robert' however, functions like balance() have access to it. Is it more or less like a private class member in C++, so that it's not possible to access it from outside of class? Or is it possible to access it in some way? The second one is more general - what is the best way to encapsulate some user data with an object like a data frame? I'd like to keep a few user attributes with a data frame... I can think of 3 possibilities, but I don't know if there's a good and reliable standard way: - I tried using attributes(), but found out that subset() gets rid of user attributes and didn't see an easy way to reset them on a subsetted frame (doing it one by one is not an option, and mostattributes() doesn't seem to be there anymore) - Something like the example used in 'scoping.R' - Using class()? Documentation for class() talks about providing methods for generic functions, but I didn't see an example of accessing user-defined data members/attributes. Many thanks! Aleksey -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Douglas Bates
2000-Jun-13 20:48 UTC
[R] Question on closure (lexical scoping) and encapsulation
Aleksey Naumov <naumov at acsu.buffalo.edu> writes:> I have two related questions about scoping and data encapsulation.> One is fairly specific - I am looking at "scoping.R" which is used > in demo(scoping) - it's an example of lexical scoping and > encapsulation. Where is the 'total' stored? It is not an attribute > in 'ross' or 'robert' however, functions like balance() have access > to it. Is it more or less like a private class member in C++, so > that it's not possible to access it from outside of class?Sort of. The functions like ross$deposit, ross$withdraw, and ross$balance all share a common environment, which is where the total is stored. > demo(scoping) ... > environment(ross$balance) <environment: 0x40b057ec> > environment(ross$withdraw) <environment: 0x40b057ec> > environment(ross$deposit) <environment: 0x40b057ec> > objects(env = environment(ross$balance)) [1] "total" I find it helpful to think of the contents of the environment as like the instance variables in a C++ or Java class. The functions defined so they share that environment are then like methods. The analogy is not perfect because the structure of elements of a class is not required to be consistent in R. The class structure is more informal than that of C++ or Java.> Or is it possible to access it in some way?You can get access to objects in that environment but you have to use functions like get and assign to manipulate them. > get("total", env = environment(ross$balance)) [1] 120> The second one is more general - what is the best way to encapsulate > some > user data with an object like a data frame? I'd like to keep a few user > attributes with a data frame... I can think of 3 possibilities, but I > don't know if there's a good and reliable standard way: > - I tried using attributes(), but found out that subset() gets rid > of > user attributes and didn't see an easy way to reset them on a subsetted > frame > (doing it one by one is not an option, and mostattributes() doesn't seem > to > be there anymore) > - Something like the example used in 'scoping.R' > - Using class()? Documentation for class() talks about providing > methods > for generic functions, but I didn't see an example of accessing > user-defined > data members/attributes.If you have the same types of information that you want to store with each instance of the data frame then you would usually extend the data.frame class. Your constructor would first create a data frame, then add the attributes that you want, then change the class to something like c("ExtendedFrame", "data.frame") and return the object. If you find that subset strips the attributes that you need then you could create a subset.ExtendedFrame that saved a local copy of those attributes, did the call to subset.data.frame (perhaps through NextMethod), and restored the attributes before returning the result.>From a quick glance at subset.data.frame, I suspect it is actually thesubscripting function "[" that is dropping the attributes you want to retain. See chapter 4 of Venables and Ripley's "S Programming" for a more complete description of how the class structure works. Please be aware that the material in their chapter 5, "New-style Classes", does not apply to R. -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Peter Dalgaard BSA
2000-Jun-13 21:43 UTC
[R] Question on closure (lexical scoping) and encapsulation
Aleksey Naumov <naumov at acsu.buffalo.edu> writes:> Dear R users, > > I have two related questions about scoping and data encapsulation. > > One is fairly specific - I am looking at "scoping.R" which is used in > demo(scoping) - it's an example of lexical scoping and encapsulation. > Where is the 'total' stored? It is not an attribute in 'ross' or > 'robert' > however, functions like balance() have access to it.It's sitting in the environment of the functions associated with ross & robert. Originally as the argument to open.account.> Is it more or less like a private class member in C++, so that it's not > possible to access it from outside of class? Or is it possible to access > it > in some way?Try stuff like ls(env=environment(ross$withdraw)) get("total",env=environment(ross$withdraw)) evalq(total <- 0, environment(robert$deposit)) robert$balance() # Rob got robbed! So it's not entirely like private parts in C++.> > The second one is more general - what is the best way to encapsulate > some > user data with an object like a data frame? I'd like to keep a few user > attributes with a data frame... I can think of 3 possibilities, but I > don't know if there's a good and reliable standard way:> - I tried using attributes(), but found out that subset() gets > rid of user attributes and didn't see an easy way to reset them on a > subsetted frame (doing it one by one is not an option, and > mostattributes() doesn't seem to be there anymore)It's there (notice that it is "mostattributes<-"), but apparently it is broken at the moment, or at least it didn't do what I expected.. This would not seem fixable for 1.1.0 on Thursday... Notice however, that nothing is keeping you from having one attribute containing several pieces of information, and copying one attribute on subsetting is not too hard. You can actually have an entire environment as an attribute. (But notice that environments are like pointers in C: if you copy one, there's still only one copy of what it contains.)> - Something like the example used in 'scoping.R'> - Using class()? Documentation for class() talks about providing > methods for generic functions, but I didn't see an example of > accessing user-defined data members/attributes.I don't think class() will get you anything useful. Something with environments, maybe. Notice, BTW, now that you're on the topic, the local() function and friends. In general, the jury is pretty much still out on how to handle the kind of construction you seem to desire. Much of the modeling code was designed for S compatibility and S doesn't have environments in the same way R does, and several people feel that we're not really utilizing the potential (then again, others value cross-platform portability). Jim Lindsey has some ideas in a paper on his website, and Doug Bates used some other ideas for the nls code. It's the kind of thing that we really should get around to discussing in a systematic manner, but tends to be difficult to get a hold on. -- O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Duncan Murdoch
2000-Jun-14 14:00 UTC
[R] Question on closure (lexical scoping) and encapsulation
On Tue, 13 Jun 2000 15:47:18 -0400, you wrote in message <39468FC6.B041ED26 at acsu.buffalo.edu>:>Dear R users, > >I have two related questions about scoping and data encapsulation. > >One is fairly specific - I am looking at "scoping.R" which is used in >demo(scoping) - it's an example of lexical scoping and encapsulation. >Where is the 'total' stored? It is not an attribute in 'ross' or >'robert' >however, functions like balance() have access to it. >Is it more or less like a private class member in C++, so that it's not >possible to access it from outside of class? Or is it possible to access >it >in some way?Others have explained that total is in an environment. Environments are somewhat like instances of classes in C++: they have inheritance (since they have parent environments), they can hold functions and data. There's no concept of "private" vs. "public": all objects in an environment are visible to any code. There's also no concept of a class type: each environment is unique, with no way to specify that two environments contain the same members. It's also rather cumbersome to extract a member from an environment, you need the "get" function. It would probably make sense to overload $ to work on environments, so that instead of Doug Bates' code get("total", env = environment(ross$balance)) you could just type environment(ross$balance)$total Print methods for environments would be nice; these should do an ls() of the environment and say what the parent environment is. It would also probably make sense to base the object oriented aspects of S on environments rather than on naming conventions and attributes, but it's probably too late to do that now. Duncan Murdoch -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._