[Rd] local variable assignment: first copies from higher frame?

Murat Tasan mmuurr at gmail.com
Thu Aug 15 01:47:43 CEST 2013


hi all -- this might not be the correct list for this
question/discussion, though R-help didn't seem like the correct venue,
either, so...

i'm looking for just some extra clarification of how local variables
are defined/bound, beyond the simple cases given in the Language
document.

the particular instance is when there is variable assignment inside a function.
normally, this creates a local variable, but there appears to be an
additional preceding step that does a bit more: the local variable is
initialized to the value of any same-named variable bound in a
containing frame.
in a sense, the lexical scoping rule is first applied to acquire a
value, and this value is then applied to the new local variable, and
is then immediately changed by the assignment operation.

i only noticed this when assigning variables to entries within a
'list' structure, like so:

tempf <- function(x, local = TRUE)
  {
    executing_environment <- environment()
    closure_environment <- parent.env(executing_environment)

    print(executing_environment)
    cat(str(mget("my_list", envir = executing_environment, inherits =
FALSE, ifnotfound = NA)[[1]]))
    print(closure_environment)
    cat(str(mget("my_list", envir = closure_environment, inherits =
FALSE, ifnotfound = NA)[[1]]))

    if(local) {
      my_list$x <- x
    } else {
      my_list$x <<- x
    }

    print(executing_environment)
    cat(str(mget("my_list", envir = executing_environment, inherits =
FALSE, ifnotfound = NA)[[1]]))
    print(closure_environment)
    cat(str(mget("my_list", envir = closure_environment, inherits =
FALSE, ifnotfound = NA)[[1]]))
  }

> my_list <- list(x = 1, y = 2)
> tempf(0, local = TRUE)
<environment: 0xcb47cb8>
 logi NA
<environment: R_GlobalEnv>
List of 2
 $ x: num 1
 $ y: num 2
<environment: 0xcb47cb8>
List of 2
 $ x: num 0
 $ y: num 2
<environment: R_GlobalEnv>
List of 2
 $ x: num 1
 $ y: num 2
> tempf(0, local = FALSE)
<environment: 0xbf4df50>
 logi NA
<environment: R_GlobalEnv>
List of 2
 $ x: num 1
 $ y: num 2
<environment: 0xbf4df50>
 logi NA
<environment: R_GlobalEnv>
List of 2
 $ x: num 0
 $ y: num 2

what surprised me in the first "local = TRUE" case is that 'y' is
still 2 in the executing environment.
so, i think my question comes down to this: when a new local variable
is created in an assignment operation, is the full value of any
matching variable in a containing frame first copied to the new local
variable?
and if so, was this chosen as a strategy specifically to allow for
these sorts of "indexed" assignment operations? (where i'm assigning
to only a single location within the vector object)?
and finally, are the other entries in the vector fully copied over, or
are they treated as "promises" similar to formal parameters, albeit
now as single entries within a containing vector?

thanks for any help on digging down a bit on the implementation here!

-murat



More information about the R-devel mailing list