eval 函数的默认参数 enclos =parent.frame() 中的奇怪行为
Strange behavior in default argument enclos =parent.frame() of eval function
我目前在理解 eval 函数的行为时遇到一些问题 - 特别是 enclos/third 参数,当没有向它提供参数时/使用默认参数 parent.fame() .
name <- function(x){
print(substitute(x))
t <- substitute(x)
eval(t, list(a=7), parent.frame())
}
z <-5
name(a+z)
# returns 12, makes sense because this amounts to
# eval(a+z, list(a=7), glovalenv())
# however the return here makes no sense to me
name2 <- function(x){
print(substitute(x))
t <- substitute(x)
eval(t, list(a=7)) # third/enclosure argument is left missing
}
z <-5
name2(a+z)
# Also returns 12
我无法理解为什么第二次调用 returns 12。根据我对 R 的理解,第二次调用应该会导致错误,因为
1) eval默认的第三个参数enclos=parent.frame(),没有指定。
2) 因此,parent.frame()是在eval的局部环境中求值的。 Hadley 在 When/how/where is parent.frame in a default argument interpreted?
中证实了这一点
3) 因此,最后一个表达式应该解析为 eval(a+z, list(a=7), execution environment of name)
4) 这应该是 return 一个错误,因为 z 既没有在 name 的执行环境中定义,也没有在 list(a=7) 中定义。
有人可以解释一下这个逻辑有什么问题吗?
z
将在函数内部可用,因为它是在 .GlobalEnv.
中定义的
简单地说,
name <- function(x) {
print(z)
}
z <- 5
name(z)
# [1] 5
因此,虽然 a
在 eval(t, list(a=7))
之前仍然未知,但 z
已经可用。如果 z
没有在 name
中定义,它将在 .GlobalEnv 中查找。可能违反直觉的是,除非您为 a
指定环境,否则 (a+z)
是未定义的。但是对于z
,就没有必要这样做了。
我目前在理解 eval 函数的行为时遇到一些问题 - 特别是 enclos/third 参数,当没有向它提供参数时/使用默认参数 parent.fame() .
name <- function(x){
print(substitute(x))
t <- substitute(x)
eval(t, list(a=7), parent.frame())
}
z <-5
name(a+z)
# returns 12, makes sense because this amounts to
# eval(a+z, list(a=7), glovalenv())
# however the return here makes no sense to me
name2 <- function(x){
print(substitute(x))
t <- substitute(x)
eval(t, list(a=7)) # third/enclosure argument is left missing
}
z <-5
name2(a+z)
# Also returns 12
我无法理解为什么第二次调用 returns 12。根据我对 R 的理解,第二次调用应该会导致错误,因为
1) eval默认的第三个参数enclos=parent.frame(),没有指定。
2) 因此,parent.frame()是在eval的局部环境中求值的。 Hadley 在 When/how/where is parent.frame in a default argument interpreted?
中证实了这一点3) 因此,最后一个表达式应该解析为 eval(a+z, list(a=7), execution environment of name)
4) 这应该是 return 一个错误,因为 z 既没有在 name 的执行环境中定义,也没有在 list(a=7) 中定义。
有人可以解释一下这个逻辑有什么问题吗?
z
将在函数内部可用,因为它是在 .GlobalEnv.
简单地说,
name <- function(x) {
print(z)
}
z <- 5
name(z)
# [1] 5
因此,虽然 a
在 eval(t, list(a=7))
之前仍然未知,但 z
已经可用。如果 z
没有在 name
中定义,它将在 .GlobalEnv 中查找。可能违反直觉的是,除非您为 a
指定环境,否则 (a+z)
是未定义的。但是对于z
,就没有必要这样做了。