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@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

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to