我目前在理解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
我无法理解为什么第二个调用返回12.根据我对R的理解,第二个调用应该导致错误,因为
1)eval的默认第三个参数enclos = parent.frame(),未指定 .
2)因此,parent.frame()在eval的本地环境中进行评估 . 哈德利在When/how/where is parent.frame in a default argument interpreted?证实了这一点 .
3)因此,最后一个表达式应该解析为eval(一个z,列表(a = 7),执行名称的环境)
4)这应该返回一个错误,因为z没有在name的执行环境中定义,也没有在list(a = 7)中定义 .
有人可以解释这个逻辑有什么问题吗?
1 回答
z
将在函数内部可用,因为它在.GlobalEnv中定义 .简单的说,
因此,虽然
a
在eval(t, list(a=7))
之前仍然是未知的,但z
已经可用 . 如果name
未在name
中定义,则将在.GlobalEnv中查找 . 可能违反直觉的是(a+z)
未定义,除非您为a
指定了一个环境 . 但是对于z
,没有必要这样做 .