I try to come up with a function factory by returning a dictionary of specialized functions, more or less like functional programming style. I try to do this in the following code.
require(hash)
names = c("aa","bb","cc");
funs = hash()
for (i in seq(length(names))) {
n = names[i]
funs[[n]] = function(x) {
print(paste(n,":",x, sep=""))
}
}
Obviously, I have 3 functions in the array; however, they all behave the same as the last function in the iteration.
> funs[["aa"]](1)
[1] "cc:1"
> funs[["bb"]](2)
[1] "cc:2"
> funs[["cc"]](3)
[1] "cc:3"
My guess is that R didn't create new function instance but reuses the same function object inside the for-loop.
I try the following in hope that R will create different function object,
funs[[n]] = eval(parse(text="function(x) { print(paste(n,':',x, sep='')) }"))
but it works the same as the first one.
Do you have an idea how to create a generator that creates different function objects?
According to Hadley's Advanced R Programmin, Lexical scoping, the variable n
in the body of functions funs[['aa']]
, funs[['bb']]
, and funs[['cc']]
are the variable n
in <environment: R_GlobalEnv>
.
For example:
> funs[["aa"]](1)
[1] "cc:1"
> n <- "1234"
> funs[["aa"]]("1")
[1] "1234:1"
To do what you want, I'll write a function which returns a function:
funs.gen <- function(n) {
force(n)
function(x) {
print(paste(n, ":", x, sep=""))
}
}
names = c("aa","bb","cc");
funs = hash()
for (i in seq(length(names))) {
n = names[i]
funs[[n]] = funs.gen(n)
}
funs[["aa"]](1)
funs[["bb"]](2)
funs[["cc"]](3)
Note that force
is used to ask R not lazy evaluate expression n
. If you remove it, then R will evaluate n
out of the for
loop which will produce the same result as your question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With