Reputation: 2932
I was playing around with R and noticed some inconsistencies with the Global Environment surrounding function calls differing from the actual global environment.
Consider the following:
> test = function ()
+ {
+ print(environmentName(as.environment(-1)))
+ print(ls(as.environment(-1)))
+ print(environmentName(.GlobalEnv))
+ print(ls(.GlobalEnv))
+ as.environment(-1)
+ }
> foo = 1
> ls()
[1] "foo" "test"
> test()
[1] ""
[1] "doTryCatch" "expr" "handler" "name" "parentenv"
[1] "R_GlobalEnv"
[1] "foo" "test"
<environment: R_GlobalEnv>
Within the function call, as.environment(-1)
returns an environment that claims it is <environment: R_GlobalEnv>
but when calling environmentName
on said environment, its name is an empty character. Furthermore, the contents of it differ from what is in the true global environment. What exactly is going on here?
I first noticed the error using mget
within a call, as a variable defined globally could not be found. This seems counter-intuitive because normally when referencing a variable within a function, R will search upwards in the enclosing environments until it finds a definition for a variable, including the global environment.
Upvotes: 9
Views: 231
Reputation: 103898
This is a consequence of lazy evaluation:
test <- function () {
e <- as.environment(-1)
list(
lazy = ls(as.environment(-1)),
eager = ls(envir = e)
)
}
foo <- 1
test()
#> $lazy
#> [1] "doTryCatch" "expr" "handler" "name" "parentenv"
#>
#> $eager
#> [1] "foo" "test"
Upvotes: 4