首页 文章

默认参数中的奇怪行为包括eval函数的parent.frame()

提问于
浏览
1

我目前在理解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 回答

  • 1

    z 将在函数内部可用,因为它在.GlobalEnv中定义 .

    简单的说,

    name <- function(x) {
      print(z)
    }
    z <- 5
    
    name(z)
    
    # [1] 5
    

    因此,虽然 aeval(t, list(a=7)) 之前仍然是未知的,但 z 已经可用 . 如果 name 未在 name 中定义,则将在.GlobalEnv中查找 . 可能违反直觉的是 (a+z) 未定义,除非您为 a 指定了一个环境 . 但是对于 z ,没有必要这样做 .

相关问题