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

Renaud Gaujoux renaud at mancala.cbio.uct.ac.za
Thu Aug 20 15:31:29 CEST 2009


Indeed.
So is there no way to do that without passing an object as parameter, 
which acts as a 'global local' workspace?
Isn't there a way to do say: "run this function and subsequent calls 
within this environment"?

Gabor Grothendieck wrote:
> A function finds its free variables in its environment.  Changing
> the environment of one function does not change the environment of
> other functions; however, if instead of messing with environments you
> use the proto solution already posted then that would handle this situation
> by passing the object from one function to another:
>
> fun.global2 <- function(obj) { message("fun.global2"); obj$setVar(4) }
> fun.global <- function(obj) { message("fun.global"); fun.global2(obj) }
> # insert main from previously posted proto solution here
> library(proto); main()
>
> On Thu, Aug 20, 2009 at 8:48 AM, Renaud Gaujoux<renaud at cbio.uct.ac.za> wrote:
>   
>> 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