Michael Lawrence
2012-Aug-05 16:00 UTC
[Rd] setting invalid fields on reference classes sometimes allowed
I've found that reference class objects tend to behave like plain old environments wrt field access, unless a method on e.g. $<- is explicitly defined. Here is a code snippet: library(methods) Foo <- setRefClass("Foo") foo <- Foo$new() foo$a <- 2 # why does this succeed? not a valid field! ## set a silly $<- method setReplaceMethod("$", "Foo", function(x, name, value) { callNextMethod(x, "b", value)}) foo$b <- 3 At first, we can set the non-existent field "a" without any error (I don't think this is the intended behavior). Then we set a silly override on $<- and things start to behave as expected: Error in envRefSetField(x, what, refObjectClass(x), selfEnv, value) : "b" is not a field in class "Foo" What am I doing wrong? Thanks, Michael [[alternative HTML version deleted]]
John Chambers
2012-Aug-05 22:54 UTC
[Rd] setting invalid fields on reference classes sometimes allowed
This doesn't seem to have anything to do with reference classes but rather is deep in the evaluator. At least when set up in the simple form of your example, the $<- method is never called. For example:> Foo <- setRefClass("Foo") > foo <- Foo$new() > find("$<-")[1] "package:base"> debug(base::`$<-`) > foo$a <- 1Other variants on this seem still not to call the replacement function, and therefore not to dispatch the correct method. I haven't had a chance to debug this at the required grubby level, but my guess is that the problem comes from base::`$<-` being a primitive, and not thinking it needs to check for methods. Various kludgey workarounds will get the evaluator's attention and fix things.> trace("$<-", sig = "Foo", browser)Tracing specified method for function "$<-" in package "base" [1] "$<-"> untrace("$<-", sig = "Foo")Untracing specified method for function "$<-" in package "base"> foo$a <- 1Error in envRefSetField(x, what, refObjectClass(x), selfEnv, value) : "a" is not a field in class "Foo" Sigh. John On 8/5/12 9:00 AM, Michael Lawrence wrote:> I've found that reference class objects tend to behave like plain old > environments wrt field access, unless a method on e.g. $<- is explicitly > defined. > > Here is a code snippet: > > library(methods) > > Foo <- setRefClass("Foo") > foo <- Foo$new() > foo$a <- 2 # why does this succeed? not a valid field! > ## set a silly $<- method > setReplaceMethod("$", "Foo", function(x, name, value) { > callNextMethod(x, "b", value)}) > > foo$b <- 3 > > > At first, we can set the non-existent field "a" without any error (I don't > think this is the intended behavior). Then we set a silly override on $<- > and things start to behave as expected: > > Error in envRefSetField(x, what, refObjectClass(x), selfEnv, value) : > "b" is not a field in class "Foo" > > What am I doing wrong? > > Thanks, > Michael > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > >
Reasonably Related Threads
- trace with reference class
- Private Variables in R5-Classes possible?
- reference classes, LAZY_DUPLICATE_OK, and external pointers
- Reference Classes: replacing '.self' with an .Rda image of '.self' from within a method? (was replacing '.self' with an .Rda image of '.self' from within a method?)
- methods package: A _R_CHECK_LENGTH_1_LOGIC2_=true error