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.

Reply via email to