R 为什么必须使用两轮表达式引用来定义局部({…})?

R 为什么必须使用两轮表达式引用来定义局部({…})?,r,non-standard-evaluation,r-environment,R,Non Standard Evaluation,R Environment,我试图了解R的local功能是如何工作的。使用它,您可以打开一个临时本地作用域,这意味着在local中发生的事情(最显著的是变量定义)将保留在local中。只有块的最后一个值返回到外部世界。因此: x <- local({ a <- 2 a * 2 }) x ## [1] 4 a ## Error: object 'a' not found 据我所知,有两轮表达式引用和后续评估: eval(quote([which expr input]),[which en

我试图了解R的
local
功能是如何工作的。使用它,您可以打开一个临时本地作用域,这意味着在
local
中发生的事情(最显著的是变量定义)将保留在
local
中。只有块的最后一个值返回到外部世界。因此:

x <- local({
    a <- 2
    a * 2
}) 

x
## [1] 4

a
## Error: object 'a' not found
据我所知,有两轮表达式引用和后续评估:

  • eval(quote([which expr input]),[which envir input])
    substitute
    生成为未计算的调用
  • 调用在
    local
    的调用者框架(在我们的例子中是全局环境)中进行评估,因此
    [任何expr输入]
    [任何envir输入]
  • 然而,我不明白为什么第二步是nessecary。为什么我不能这样简单地定义
    local

    local <- function(expr, envir = new.env()){
        eval.parent(substitute(eval(quote(expr), envir)))
    }
    
    local2 <- function(expr, envir = new.env()){
        eval(quote(expr), envir)
    }
    
    因此,
    a
    泄露给全球环境。为什么会这样

    编辑:更神秘的是:为什么它不会发生在:

    eval(quote({a <- 2; a*2}), new.env())
    ## [1]  4
    a
    ## Error: object 'a' not found
    

    eval(quote)({a参数作为承诺传递给R函数。除非特别要求值,否则不会对其进行计算。因此,请参见

    # clean up first
    if exists("a") rm(a)
    
    f <- function(x) print(1)
    f(a<-1)
    # [1] 1
    a
    # Error: object 'a' not found
    g <- function(x) print(x)
    g(a<-1)
    # [1] 1
    a
    # [1] 1
    
    你好像在哪里

    j<- function(x) {
      quote(x)
    }
    j(a<-1)
    # x
    
    看看这里的行为

    local2 <- function(expr, envir = new.env()){
        eval(quote(expr), envir)
    }
    local2({a<-5; a})
    # [1] 5
    local2({a<-5; a}, list(a=100, expr="hello"))
    # [1] "hello"
    

    local2将参数作为承诺传递给R函数。除非特别请求值,否则不会对其求值。因此,请参见

    # clean up first
    if exists("a") rm(a)
    
    f <- function(x) print(1)
    f(a<-1)
    # [1] 1
    a
    # Error: object 'a' not found
    g <- function(x) print(x)
    g(a<-1)
    # [1] 1
    a
    # [1] 1
    
    你好像在哪里

    j<- function(x) {
      quote(x)
    }
    j(a<-1)
    # x
    
    看看这里的行为

    local2 <- function(expr, envir = new.env()){
        eval(quote(expr), envir)
    }
    local2({a<-5; a})
    # [1] 5
    local2({a<-5; a}, list(a=100, expr="hello"))
    # [1] "hello"
    

    local2谢谢,带有promise参数的提示已经帮了大忙。但是,我无法理解您对
    eval.parent
    调用的解释。您声明调用范围中的变量(因此全局环境)可以使用。但是,
    local3似乎也可以这样做,我认为这更为明确。如果查看
    eval()
    的默认值,如果您像您一样为
    envir
    参数提供环境,则默认情况下假定封闭环境为
    enclose=parent.frame()
    。您可以使用
    enclose=baseenv()
    来更改该行为。谢谢,带有promise参数的提示已经帮了大忙。但是,我无法理解您对
    eval.parent
    调用的解释。您声明的是调用范围中的变量(因此全局Env)可以使用。但是,
    local3似乎也可以这样做,我认为这更为明确。如果查看
    eval()
    的默认值,如果您像您一样为
    envir
    参数提供环境,则默认情况下假定封闭环境为
    enclose=parent.frame()
    。您可以使用
    enclose=baseenv()