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<ren...@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<geto...@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@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. >>> >>> > > ______________________________________________ R-help@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.