8 return(f)
9 }
Let’s try this out before going into the internal details:
> c1 <- counter()
> c2 <- counter()
>c1
function() {
ctr <<- ctr + 1
cat("this count currently has value",ctr,"\n")
}
<environment: 0x8d445c0>
>c2
function() {
ctr <<- ctr + 1
cat("this count currently has value",ctr,"\n")
}
<environment: 0x8d447d4>
> c1()
this count currently has value 1
> c1()
this count currently has value 2
> c2()
this count currently has value 1
> c2()
this count currently has value 2
> c2()
this count currently has value 3
> c1()
this count currently has value 3
Here, we calledcounter()twice, assigning the results toc1andc2. As ex-
pected, those two variables will consist of functions, specifically copies off().
However,f()accesses a variablectrthrough the superassignment opera-
tor, and that variable will be the one of that name that is local tocounter(),as
it is the first one up the environment hierarchy. It is part of the environment
off()and, as such, is packaged in what is returned to the caller ofcounter().
The key point is that each timecounter()is called, the variablectrwill
be in a different environment (in the example, the environments were at
memory addresses 0x8d445c0 and 0x8d447d4). In other words, different
calls tocounter()will produce physically differentctrs.
The result, then, is that our functionsc1()andc2()serve as completely
independent counters, as seen in the example, where we invoke each of
them a few times.
R Programming Structures 175