5

I am using the address() function in the pryr package in R, and was wondering if this following result is to be expected...

x <- 1:10
add <- function(obj){address(obj)}
address(x)
# [1] "0x112d007b0"
add(x)
# [1] "0x11505c580"

i.e. 0x112d007b0 != 0x11505c580

I was hoping that they were going to be the same value...is there a way to get adjust the function add above to ensure it does get the same value? i.e. get the address in the parent environment?

Frank
  • 66,179
  • 8
  • 96
  • 180
h.l.m
  • 13,015
  • 22
  • 82
  • 169
  • 1
    Hm, that's odd. When I use `address` from data.table (which I'd thought until now was a base function), it is the same for those two. – Frank Oct 22 '15 at 18:10
  • 1
    Hmm, interesting, it always gives a new address each time you run `add(x)`. I guess it gives a new address within the lexical scope of the function as function environment is temporary and it runs `parent.frame()` under the hood. `tracemem` works fine in the function too, so you can just use it instead. – David Arenburg Oct 22 '15 at 18:14
  • @bunk what do you have against `tracemem(x)`? :) – David Arenburg Oct 22 '15 at 21:07

1 Answers1

3

pryr:::address is defined as function(x) address2(check_name(substitute(x)), parent.frame()). If you wrap pryr:::address in another function its parent.frame() changes. E.g.:

myfun = function() parent.frame()
myfunwrap = function() { print(environment()); myfun() }
myfun()
#<environment: R_GlobalEnv>
myfunwrap()
#<environment: 0x063725b4>
#<environment: 0x063725b4>
myfunwrap()
#<environment: 0x06367270>
#<environment: 0x06367270>  

Specifically, unless I've lost it somewhere, pryr::address seems to work like the following:

ff = inline::cfunction(sig = c(x = "vector", env = "environment"), body = '
    Rprintf("%p\\n", findVar(install("x"), env));
    return(eval(findVar(install("x"), env), env)); //pryr::address does not evaluate
')  #this is not a general function; works only for variables named "x"
assign("x", "x from GlobalEnv", envir = .GlobalEnv)
ff1 = function(x) ff(x, parent.frame())
ff2 = function(x) ff1(x)

pryr::address(x)
#[1] "0x6fca100" 

ff(x, .GlobalEnv)
#0x06fca100
#[1] "x from GlobalEnv"
ff1(x)
#0x06fca100
#[1] "x from GlobalEnv"
ff1(x)
#0x06fca100
#[1] "x from GlobalEnv"
ff2(x)
#0x06375340
#[1] "x from GlobalEnv"
ff2(x)
#0x0637480c
#[1] "x from GlobalEnv"

I'm not sure how that can be "fixed" (sometimes it might be wanted to behave like this) other than doing something like:

add = pryr::address
add(x)
#[1] "0x6fca100"
alexis_laz
  • 12,884
  • 4
  • 27
  • 37