我试图在一系列函数调用中使用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()
似乎不起作用。
答案 0 :(得分:14)
你被框架和环境之间的微妙差异所绊倒(由于框架是环境,或者环境可能是框架,因此更加微妙)以及lexical and dynamic scoping之间的差异。 parent.frame
的帮助页面中有一些详细信息,其他地方也有各种文档。
尝试简化:
您的getter
函数有自己的environment,其中存储了该函数的本地变量(在这种情况下为x
)。由于R是词法范围,这意味着函数环境具有父环境,该环境由定义函数的位置定义,在这种情况下是全局环境(如果它是在另一个函数内部定义的那么父环境将是env for the功能)。
当您致电f1
并调用getter
时,getter会尝试查找变量foo
,它首先在自己的环境中查找,但在那里找不到它,然后查看其中父环境,它是全局环境并查找foo
,其值为1.
你的想法与动态范围有关,框架是近似的。调用f1
时,它会获得自己的环境(foo
将为其分配值2),然后调用getter
函数。 foo
的环境不是getter
的env(词法范围)的父级,但f1
的环境是getter
的父框架,因为getter
从f1
调用,所以要查看f1
的环境,你需要告诉get
函数查看父框架而不是父框架。
总结是父环境是定义函数的环境(词法范围),父框架是调用函数的框架/环境(模拟动态范围)。
答案 1 :(得分:6)
如果您定义getter
以查看父框架,则可以正常工作:
getter <- function(x) get(x, envir=parent.frame())
然后:
getter("foo")
[1] 1
f1()
[1] 2