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.
The environment is a virtual space that is triggered when an interpreter of a programming language is launched. Simply, the environment is a collection of all the objects, variables, and functions. Or, Environment can be assumed as a top-level object that contains the set of names/variables associated with some values.
The parent environment of a function is the environment in which the function was created. If a function was created in the execution environment (for example, in the global environment), then the environment in which the function was called will be the same as the environment in which the function was created.
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With