【问题标题】:Limiting variable scope限制变量范围
【发布时间】:2010-07-18 22:43:25
【问题描述】:

我正在尝试编写一个函数,它限制了 R 变量的范围。例如,

source("LimitScope.R")
y = 0
f = function(){
   #Raises an error as y is a global variable
   x = y
}

我想测试变量环境,但不确定如何执行此操作。

原因

我向本科生教授 R。在他们最初的几个实践中,他们中的一些人总是忘记变量范围,所以他们提交的函数不起作用。例如,我总是得到类似的东西:

n = 10
f = function(x){
  #Raises an error
  #as I just source f and test it for a few test cases.
  return(x*n)
}

我想要一个“关闭”范围的快速功能。正如您可以想象的那样,它不必特别强大,因为它只是为少数实用程序提供的。

【问题讨论】:

标签: r scope


【解决方案1】:

我不确定您是否希望这样做,但 local() 函数应该会有所帮助,codetools 库也应该如此。

在你的例子中,试试

f = local( function() { ... }, baseenv())

它并不能完全满足您的需求,但它应该让您更接近。

【讨论】:

    【解决方案2】:

    您可以使用此函数强制变量为本地版本:

    get_local <- function(variable)
    {
      get(variable, envir = parent.frame(), inherits = FALSE)  
    }
    

    比较这些案例

    y <- 0    
    f <- function()
    {
      x <- y
    }    
    print(f())        # 0
    
    y <- 0    
    f <- function()
    {
      y <- get_local("y")
      x <- y
    }    
    print(f())        # Error: 'y' not found
    

    根据您的操作,您可能还想使用formalArgsformals 来检查y 是否是f 的参数。

    g  <- function(x, y = TRUE, z = c("foo", "bar"), ...) 0
    
    formalArgs(g)
    # [1] "x"   "y"   "z"   "..."
    
    formals(g)
    #$x
    #
    #
    #$y
    #[1] TRUE
    #
    #$z
    #c("foo", "bar")
    #
    #$...
    

    编辑:“如何在不更改函数内容的情况下关闭词法作用域”这一更普遍的观点更难解决。我相当确定范围规则在 R 中已经根深蒂固。另一种方法可能是使用 S-Plus,因为它有 different scoping rules

    【讨论】:

      【解决方案3】:

      您可以使用exists('y',envir=.GlobalEnv)检查 y 是否存在于全局环境中

      【讨论】:

        【解决方案4】:

        偶尔发生在我身上的是,我在 ESS 中有一个分屏,左边是 R 代码的文件缓冲区,右边是解释器。当我在缓冲区中调试我正在处理的代码时,我可能在解释器中设置了一些值。那么缓冲区中的代码可能会意外引用我在解释器中设置的内容。除非我每次都在新的解释器中评估我的缓冲区,否则很难发现问题,这不是 ESS 默认的工作方式。

        如果这是您经常看到的那种问题,那么您来源的东西中的 rm(list=ls(envir=.GlobalEnv)) 可能会有所帮助,但这当然会产生其他问题,例如擦除它们曾经存在的任何东西用于在调试等时保持状态。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-11-17
          • 2014-04-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多