问题
I'd like to specify functions in a flexible way. How can I make sure that the environment of a given function does not change when I create another function just after it.
To illustrate, this works properly:
make.fn2 <- function(a, b) {
fn2 <- function(x) {
return( x + a + b )
}
return( fn2 )
}
a <- 2; b <- 3
fn2.1 <- make.fn2(a, b)
fn2.1(3) # 8
fn2.1(4) # 9
a <- 4
fn2.2 <- make.fn2(a, b)
fn2.2(3) # 10
fn2.1(3) # 8
This does not
make.fn2 <- function(a, b) {
fn2 <- function(x) {
return( x + a + b )
}
return( fn2 )
}
a <- 2; b <- 3
fn2.1 <- make.fn2(a, b)
a <- 4
fn2.2 <- make.fn2(a, b)
fn2.1(3) # 10
fn2.1(4) # 11
fn2.2(3) # 10
fn2.1(3) # 10
回答1:
This is due to lazy evaluation. The function is not actually constructed until it is called. So, in the second case, both times the new version of a
is picked up. See also this other question.
You can solve this issue by using force
:
make.fn2 <- function(a, b) {
force(a)
force(b)
fn2 <- function(x) {
return( x + a + b )
}
return( fn2 )
}
This forces the function to pick up the values of a
and b
when the function is created, not when the function is called. It produces the correct output:
> a <- 2; b <- 3
> fn2.1 <- make.fn2(a, b)
>
> a <- 4
> fn2.2 <- make.fn2(a, b)
>
> fn2.1(3) # 10
[1] 8
> fn2.1(4) # 11
[1] 9
> fn2.2(3) # 10
[1] 10
> fn2.1(3) # 10
[1] 8
>
来源:https://stackoverflow.com/questions/21628656/variable-scope-in-r-functions