R行为中的评估

eval in R behavior

我正在尝试了解函数内部的 eval 函数行为,因此假设这是我的设置:

定义了两个全局变量x和a

x <- 'a'
a <- 'c'

然后用三个打印语句定义了一个函数 f,我对 eval 和 envir 参数默认为 parent.frame() 的事实感到困惑,但是,如果我故意这样写,结果是不同的。为什么?

下面是代码加注释可以加深理解,非常感谢解答注释提前解决这个问题。

f <- function(x){
  ## 1st statement, I get it that evaluation should be done in current environment 
  print(eval(quote(x), envir = environment()))
  
  
  ## 2nd statement, This I don't get, as the default is parent.frame(), shouldn't it be 
  ## evaluated in the calling scope of function which is global environment. As per 
  ## documentation parent.frame() is the default then why this result evaluates to current
  ## environment, whereas the last print statement when specifically mentions parent.frame gives a different result entirely.
  ## Note the documentation says: If envir is not specified, then the default is parent.frame() (the environment where the call to eval was made).
  ## So, my understanding of parent.frame is that it is that frame where calls are happening(basically calling environment), Am I mistaken here?
  print(eval(quote(x)))
  
  ## 3rd , This behaviour seems okay as parent.frame is referencing the calling scope which is global
  print(eval(quote(x), envir=parent.frame()))
}

输出:

#> f(a)
#[1] "c"
#[1] "c"
#[1] "a"

提供的参数和默认参数的范围不同。

提供的参数在调用者的评估框架中进行评估,即您的示例中的 f。所以envir设置为那个调用的parent.frame,也就是全局环境

默认参数在定义它们的函数的评估框架中评估,在您的示例中为 eval。在eval()调用中,父框架是f的评估框架。

如果你仔细想想,这很有道理。作为 f() 的作者,您应该知道在评估它时哪些变量是可见的,因此那些是用于评估参数表达式的变量。另一方面,eval() 的作者不知道它的调用者可以使用什么,所以必须在它自己的评估框架中评估默认参数。