Thanks Duncan, I agree that touching the environments is risky and not
robust. I rather go for another solution.
But the function solution still require to pass an extra object to the
user's function. I'd like the user to simply be able to call function
setVar as if it was a standard R function (visible from any of his --
possibly nested -- functions), but this function would act on a variable
local to the main call, that I can setup on runtime. This variable
should be protected from direct access as much as possible (my idea with
the local layer was something to implement kind of a private variable).
Maybe it's just impossible ?
-- Sorry to insist :) --
Renaud
Duncan Murdoch wrote:
On 8/20/2009 4:27 AM, Renaud Gaujoux 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.
The best way to do this is to pass the function (setVar below) as an
argument to the user's function. If it's the user's function, you
have no business messing with it by changing its environment. How do
you know the user didn't spend hours working out some crazy scheme of
creating a nested function with a carefully crafted environment, and
evaluation of his function depends on you leaving it alone?
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) #
}
Pass setVar as an arg:
fun.global <- function(setVar) {
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))
}
I wouldn't bother with the extra layer of local(), just put l.var in
main's evalution frame. (Since you're the one writing setVar, you can
avoid any name clashes.) That is:
main <- function() {
message('main')
l.var <- 0
setVar <- function(value) {
message('setVar')
l.var <<- value
}
fun.global(setVar)
print(l.var)
}
Duncan Murdoch
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.