ruedi ruedi - 1 year ago 93
R Question

Understanding Enclosing Environment

I have the following code

new_counter <- function(){
ij <- 0
ij <<- ij+1

counter_one <- new_counter()
counter_two <- new_counter()


from this tutorial.

They write:

The counters get around the “fresh start” limitation by not modifying
variables in their local environment. Since the changes are made in
the unchanging parent (or enclosing) environment, they are preserved
across function calls.

This is what I think is going on: The
function is created in the
enclosing environment
) as well as the
function. But the
execution environment
function is one level higher than the counter_one functions. This is usually temporary but this time it is not since we have an enclosure function.

But how can I see 'this' enclosing enviroment and that they are one level apart? Using (pryr)
and environment delivers for both functions the global environment.

They talk about two different environments:

  1. 'in theire local environment'

  2. 'in the unchainging parent environment'

So to me these are two different environments but if they differ they probably have a different name! How can I find out the name? Using


both deliver the global environment but looking in the enumeration above this must be two different ones.

Answer Source

This should hopefully clarify what is happening. Note that the enclosing environment of new_counter is the global environment but the environments of counhter_one and counter_two are the environments within the two execution instances of new_counter. Normally a function's enclosing environment is its lexical environment (the environment where it is defined) but in some situations this varies.

new_counter <- function(){
  e <- environment()
  ij <- 0
    ij <<- ij+1

counter_one <- new_counter()  # A
counter_two <- new_counter()  # B


environment(new_counter) # global environment

environment(counter_one) # see output of A
environment(counter_two) # see output of B

Here is a simpler example that shows that a function can be located in one environment yet its enclosing environment can be a different environment. In this case f is in the global environment; however, its enclosing environment is e and not the global environment.

e <- new.env()
e$x <- 1
x <- 2
f <- function() x
environment(f) <- e
## [1] 1

There is some discussion here:

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download