限制变量范围

时间:2010-07-18 22:43:26

标签: r scope

我正在尝试编写一个限制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)
}

我正在使用一个能够“关闭”范围的快速功能。你可以想象它不一定非常强大,因为它只是为少数实用提供。

4 个答案:

答案 0 :(得分:4)

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

在您的示例中,请尝试

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

它并不能完全符合您的要求,但它可以让您更接近。

答案 1 :(得分:3)

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

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

根据您的操作,您可能还想查看yf的参数,使用formalArgs还是formals

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

答案 2 :(得分:1)

您可以使用exists('y',envir=.GlobalEnv)

检查全局环境中是否存在y

答案 3 :(得分:0)

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

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