[Rd] Reference Class error message: may be caused by lazy evaluation?

Martin Morgan mtmorgan at fhcrc.org
Thu Jun 9 19:28:57 CEST 2011


On 06/09/2011 10:11 AM, John Chambers wrote:
> Good catch.
>
> Here's the problem. To save space and time, reference methods are not
> all copied to every object in the class. Instead, the methods are copied
> in when first accessed. Methods are functions which use the object as
> their environment. So that is the sense in which "lazy evaluation" is
> involved.
>
> If a method calls another method (add() calling addOne() in your
> example), then the method for the `$` operator knows to copy over that
> method (addOne). (The second of my examples below shows this.) But if
> the method _refers_ to another method without calling it, the code
> analysis does not currently catch the reference.
>
> We can fix that, although it's a little subtle. Meanwhile, your
> showself() is a good workaround.
>
> For anyone interested, the code below illustrates.
>
> One point of style. I would suggest saving the generator object and
> calling its $new() method, as below, rather than treating the reference
> class as an S4 class. The result is identical AFAIK, but the style is
> more typical of such OOP languages.

I wonder if this is an opportunity to be more authoritarian? It seems to 
be a common temptation to call S4 new() and, for me, introduces a 
source of uncertainty / confusion when trying to understand why code 
does not work.

Martin

>
> John
>
> ---------------------------
>  > tc <- setRefClass("testclass", fields = list(a = "numeric"),
> + methods = list(
> ....
> + ))
>  > t1 <- tc$new(a=1)
>  > ss = t1$show
>  > ss
> Class method definition for method show()
> function ()
> {
> print(addOne)
> }
> <environment: 0x10188d5f8>
>  > ev = environment(ss)
>  > ev
> <environment: 0x10188d5f8>
>  > t1
> An object of class "testclass"
> <environment: 0x10188d5f8> # <<<< same environment
>  > objects(ev)
> [1] "a" "show" #<<<< not addOne, though
>  > t1$addOne
> Class method definition for method addOne()
> function ()
> {
> a <<- a + 1
> print(a)
> }
> <environment: 0x10188d5f8>
>  > objects(ev)
> [1] "a" "addOne" "show" # <<<< now addOne is there
>
>
> On 6/8/11 4:38 PM, Tengfei Yin wrote:
>> Dear All,
>>
>> I came across an error message recently when constructing a reference
>> class,
>> an example is attached below, it looks like only if I call a specific
>> method
>> in advance, otherwise it cannot be found in defined method without using
>> .self, this make it difficulty that sometimes in my initialize method, I
>> need to call other method defined in the same reference class, the
>> workaround for this is add .sef to it.
>>
>>
>> ############### example begin ############################
>> setRefClass("testclass", fields = list(a = "numeric"),
>> methods = list(
>> addOne = function(){
>> a<<- a+1
>> print(a)
>> },
>> add = function(){
>> addOne()
>> },
>> show = function(){
>> print(addOne)
>> },
>> showself = function(){
>> print(.self$addOne)
>> }
>> ))
>>
>> obj<- new("testclass", a = 1)
>> obj$show() #
>> Error in print(addOne) : object 'addOne' not found
>> obj$addOne() #
>> return 2, works
>> obj$show() #
>> after calling addOne(), show() works
>>
>> ## works if use .self$...
>> obj2<- new("testclass", a = 1)
>> obj2$showself()
>>
>> ## works when call the method directly within another method
>> obj3<- new("testclass", a = 1)
>> obj3$add()
>>
>> ################ end ##########################################
>>
>> I am still learning this new technique, if I made any mistake I didn't
>> notice before, please let me know, I will really appreciate that.
>>
>> Thanks a lot!
>>
>> Tengfei
>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel


-- 
Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

Location: M1-B861
Telephone: 206 667-2793



More information about the R-devel mailing list