9

我正在尝试get在一系列函数调用中使用,但对象名称的查找似乎跳过了环境。例如:

foo <- 1 # variable in .GlobalEnv

getter <- function(x) {get(x)}
getter("foo") # returns 1, which is expected

f1 <- function() {
  foo <- 2 # local variable in the function scope
  getter("foo")
}

f1() # still returns 1, would've expected to return 2

为什么调用f1返回foo全局环境中的而不是foo调用函数环境中的?

如何get查看调用函数的环境?设置pos = sys.parent()似乎不起作用。

4

2 回答 2

16

你被框架和环境之间的细微差别(这更加微妙,因为框架是环境,或者环境是框架)以及词法和动态作用域之间的差异所困扰。帮助页面中有一些详细信息,parent.frame以及分布在各种文档中的其他地方。

尝试和简化:

您的getter函数有自己的环境,其中存储了该函数的本地变量(x在这种情况下)。由于 R 是词法范围的,这意味着函数环境具有由定义函数的位置定义的父环境,在这种情况下,全局环境(如果它是在另一个函数内部定义的,那么父环境将是该函数的 env功能)。

当您调用f1并且它调用getter然后 getter 尝试查找变量foo时,它首先在它自己的环境中查找,在那里没有找到它,然后在它的父环境中查找,即全局 env 并找到foo值为 1。

您的想法沿着框架近似的动态范围界定的路线进行。当f1被调用时,它会获得自己的环境(其中foo将被分配值 2),然后它调用该getter函数。的环境foo不是getterenv 的父级(词法作用域),但 的环境f1是 的父框架,getter因为getter是从 调用的f1,所以要在环境中查找,f1您需要告诉get函数在父框架中查找比父环境。

总结是父环境是定义函数的环境(词法范围),父框架是调用函数的框架/环境(模拟动态范围)。

于 2012-09-19T17:11:02.933 回答
6

如果您定义getter在父框架中查看,它可以工作:

getter <- function(x) get(x, envir=parent.frame())

然后:

getter("foo")
[1] 1

f1()
[1] 2
于 2012-09-19T09:52:14.680 回答