[R] eval and evironments: call local function in a global function

Renaud Gaujoux renaud at mancala.cbio.uct.ac.za
Thu Aug 20 14:48:39 CEST 2009


Hi Gabor,

thanks.
Indeed I reckon implementing it using an object would be better, but I 
wanted to keep it as simple as possible for the end user, by hiding the 
object mechanism. The user would not have to define its function with an 
extra parameter, maybe obscure to him.

My problem now is that the solution you proposed with the environment 
does not work if the user defined function actually calls function 
setVar from another function, that I can't know about. Say if function 
fun.global is as follows:

fun.global2 <- function(){
    message('fun.global2')
    setVar(4)
}

fun.global <- function(){
    message('fun.global')   
    fun.global2()   
}

What I thought is that once set running environment as you proposed, the 
following function calls would all inherit from it. I guess I'm wrong.
It looks very strange to me, as in other interpreted languages there 
would not be any problem with such calls. Do you know exactly how do the 
environments work?
I might end up using the object solution to make it clean.

Thanks

Gabor Grothendieck wrote:
> I am not sure what the purpose of workspace is so I
> have eliminated it in the following.  We just use the
> environment within main and when main exits all its
> variables go too so that seems sufficient.
>
> fun.global <- function() { message('fun.global'); setVar(5) }
>
> main <- function() {
> 	l.var <- 0
> 	setVar <- function(value) { message("set Var"); l.var <<- value }
> 	environment(fun.global) <- environment()
> 	fun.global()
> 	print(l.var)
> }
> main()
>
> We could also recognize that there is an implicit object here with
> methods setVar and fun.global and property l.var so using proto:
>
> library(proto)
> fun.global <- function(obj) { message("setVar"); obj$setVar(5) }
>
> main <- function() {
>     p <- proto(l.var = 0,
>            setVar = function(obj, value) { message("setVar");
> obj$l.var <- value },
>            fun.global = fun.global)
>     p$fun.global()
>     print(p$l.var)
> }
> main()
>
> On Thu, Aug 20, 2009 at 4:27 AM, Renaud Gaujoux<getoxxx at gmail.com> wrote:
>   
>> Hi,
>>
>> in my project I want the user to be able to write hook functions that are in
>> turn called in my main code. I'd like the user's hooks to be able to call
>> some function that set a variable outside their running environment. The
>> trick is that this variable is not global, but defined on runtime before
>> calling the hooks, and I don't want to leave any trace (i.e. global
>> variables) after the main code has finished.
>>
>> I thought that the following would work but it doesn't. I guess I got too
>> messy with environment and enclosures:
>>
>> # global function defined by the user
>> fun.global <- function(){
>>   message('fun.global')
>>   setVar(5) #
>> }
>>
>>
>> # my main code
>> main <- function(){
>>   message('main')
>>
>>   # define a function to set some local variable
>>   setVar <- local({
>>   l.var <- 0
>>   function(value){
>>       message('setVar')
>>      l.var <<- value
>>   }
>>   })
>>   .workspace <- environment(setVar)
>>   environment(setVar) <- new.env()
>>
>>   eval(fun.global(), enclos=environment(setVar))
>>   print(get('l.var', envir=.workspace, inherits=FALSE))
>> }
>>
>> main()
>>
>> I get the following output:
>>     
>>> main
>>> fun.global
>>> Error in fun.global() : could not find function "setVar"
>>>       
>> There is definitely a problem of lookup somewhere. I first tried without
>> eval, as I thought that function setVar would then be defined in a parent
>> environment of the call to fun.global, but it does not work either.
>> Can anybody tell me what's the problem and how I should do my stuff?
>>
>> Thanks,
>> Renaud
>>
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>>
>>




More information about the R-help mailing list