问题在于,它get
查看了它调用的环境,但在这里我们传递get
到mapply
然后get
从本地环境调用mapply
。如果x
在本地环境中找不到,mapply
那么它会查看该环境的父环境,即查看environment(mapply)
(这是定义 mapply 的词法环境,其中是基本命名空间环境);如果它也不存在,它会查看它的父级,即全局环境,即您的 R 工作区。
这是因为 R 使用词法作用域,而不是动态作用域。
我们可以通过获取存在于 中的变量来证明这一点mapply
。
x <- 2
b2<-function(){
x<-1
mapply(get, "USE.NAMES")
}
b2() # it finds USE.NAMES in mapply
## USE.NAMES
## TRUE
除了问题中显示的解决方法之外,这也有效,因为它会导致搜索在未能找到它后MoreArgs
查看本地环境。(这只是为了说明正在发生的事情,在实际实践中,我们更喜欢问题中显示的解决方法。)b
mapply
x <- 2
b3 <-function(){
x<-1
environment(mapply) <- environment()
mapply(get, "x")
}
b3()
## 1
添加了扩展解释。另请注意,我们可以像这样查看环境链:
> debug(get)
> b()
debugging in: (function (x, pos = -1L, envir = as.environment(pos), mode = "any",
inherits = TRUE)
.Internal(get(x, envir, mode, inherits)))(dots[[1L]][[1L]])
debug: .Internal(get(x, envir, mode, inherits))
Browse[2]> envir
<environment: 0x0000000021ada818>
Browse[2]> ls(envir) ### this shows that envir is the local env in mapply
[1] "dots" "FUN" "MoreArgs" "SIMPLIFY" "USE.NAMES"
Browse[2]> parent.env(envir) ### the parent of envir is the base namespace env
<environment: namespace:base>
Browse[2]> parent.env(parent.env(envir)) ### and grandparent of envir is the global env
<environment: R_GlobalEnv>
因此,可能遵循的环境的祖先是这样的(箭头指向父级的地方):
local environment within mapply --> environment(mapply) --> .GlobalEnv
其中environment(mapply)
equalsasNamespace("base")
是基本命名空间环境。