Re: possible RApache bug

24 views
Skip to first unread message

Jeffrey Horner

unread,
May 6, 2013, 5:29:13 PM5/6/13
to Jeremy Stephens, rr...@googlegroups.com, rap...@googlegroups.com
A couple of observations:

(cross-posting this as it's relevant for rook and rApache groups; hope
you don't mind)

1. setRefClass stores it's class definition based on it's argument
"where". When you were running your code within R without rApache, you
were probably assigning it to the global environment. In your case
under rApache it's stored in an anonymous environment specific to your
file. Read more about this argument in ?getRefClass.

2. Reference Class methods have a different scope chain than typical
function calls. They can only see the other objects and methods of the
class, and failing that I believe they look to the global environment
and then the rest of the search path. In your case Foo would never be
found in Bar::call since it's lexically found in the same file but not
as I described. Make sense?

Here's a solution that works:

# Explicitly add the reference class to the global environment
setRefClass('Foo', methods = list(foo = function() 'foo'),where=globalenv())

Bar <- setRefClass(
'Bar',
methods = list(
call = function(env) {

# Create a local variable Foo. Note that I had to qualify
getRefClass since there's a
# parent method named getRefClass which takes different
arguments. You can chalk
# that up to bad language design or "just another R quirk" :)
# And of course we know where 'Foo' is so we say where it is.

Foo <- methods::getRefClass('Foo',where=globalenv())

req <- Rook::Request$new(env)
res <- Rook::Response$new()
foo <- Foo$new()
res$write(foo$foo())
res$finish()
}
)
)

On Mon, May 6, 2013 at 4:00 PM, Jeremy Stephens
<jeremy.f...@vanderbilt.edu> wrote:
> Jeff,
>
> I've defined a reference class that I'm using inside of a Rook app.
> Something like this:
>
> Foo <- setRefClass('Foo', methods = list(foo = function() 'foo'))
> Bar <- setRefClass(
> 'Bar',
> methods = list(
> call = function(env) {
> req <- Rook::Request$new(env)
> res <- Rook::Response$new()
> foo <- Foo$new()
> res$write(foo$foo())
> res$finish()
> }
> )
> )
>
> When I run this in R interactively with Rhttpd, it works. In the RApache
> environment, though, it can't find the Foo class.
>
> Any ideas?
>
> Thanks,
> Jeremy



--
http://biostat.mc.vanderbilt.edu/JeffreyHorner

Jeremy Stephens

unread,
May 6, 2013, 5:49:54 PM5/6/13
to Jeffrey Horner, rr...@googlegroups.com, rap...@googlegroups.com
Jeff,

Cool, thanks for the help. The only problem I see with this solution is
that since the reference class lives in the global environment, any
other R app running in the RApache space could access Foo and possibly
redefine it.

-- Jeremy

Jeffrey Horner

unread,
May 6, 2013, 5:53:02 PM5/6/13
to rr...@googlegroups.com
You are right about that, but I think in the general case that won't
be a problem... or rather... when rApache and rook become soooo
popular that it is a problem.... well that'd be a good problem, right?
;)

On Mon, May 6, 2013 at 4:49 PM, Jeremy Stephens
> --
> You received this message because you are subscribed to the Google Groups
> "rRook" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rrook+un...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>



--
http://biostat.mc.vanderbilt.edu/JeffreyHorner

Jeremy Stephens

unread,
May 7, 2013, 11:44:43 AM5/7/13
to Jeffrey Horner, rr...@googlegroups.com, rap...@googlegroups.com
This actually works, too:

Foo <- setRefClass(
'Foo',
methods = list(foo = function() 'foo'),
where = environment()
)
Bar <- setRefClass(
'Bar',
methods = list(
call = function(env) {
req <- Rook::Request$new(env)
res <- Rook::Response$new()

Foo <- methods::getRefClass('Foo', where = globalenv())
foo <- Foo$new()
res$write(foo$foo())
res$finish()
}
),
where = environment()
)

-- Jeremy

Jeffrey Horner

unread,
May 7, 2013, 11:48:02 AM5/7/13
to rr...@googlegroups.com
Right, because environment() just returns the global environment.

Jeremy Stephens

unread,
May 7, 2013, 11:57:54 AM5/7/13
to Jeffrey Horner, rr...@googlegroups.com, rap...@googlegroups.com
Oops, I thought just using:

where = environment()

would do the trick. I forgot to remove the other fix, hah. It doesn't work.

-- Jeremy

Jeremy Stephens

unread,
May 7, 2013, 12:03:58 PM5/7/13
to Jeffrey Horner, rr...@googlegroups.com, rap...@googlegroups.com
Here's the corrected version:

Foo <- setRefClass(
'Foo',
methods = list(foo = function() 'foo'),
where = environment()
)
Bar <- setRefClass(
'Bar',
methods = list(
call = function(env) {
req <- Rook::Request$new(env)
res <- Rook::Response$new()

Foo <- methods::getRefClass('Foo', where = environment())
foo <- Foo$new()
res$write(foo$foo())
res$finish()
}
),
where = environment()
)

You need to use the getRefClass trick, but specify the current
environment. Sorry for the extra e-mails.

-- Jeremy
Reply all
Reply to author
Forward
0 new messages