11

Can I access data.table object created in current R session by its memory address or pointer?

library(data.table)

DT <- data.table(a = 1:10, b = letters[1:10])
address(DT)
# [1] "0x6bf9b90"
attr(DT,".internal.selfref",TRUE)
# <pointer: 0x2655cc8>
zx8754
  • 52,746
  • 12
  • 114
  • 209
jangorecki
  • 16,384
  • 4
  • 79
  • 160
  • 1
    let's suppose for a moment you could - how would you use that? – eddi Apr 26 '15 at 01:21
  • @eddi I want to combine with my `read.only` attribute for data.table and be able to re-query any data.table object from any environment in my session just by maintaining *address / pointer* to read-only data.table. Mostly for interactive use. – jangorecki Apr 26 '15 at 01:41

1 Answers1

4

This is somewhat of a silly way of doing it (as compared to how you can cast pointers in e.g. C++), but you could do:

# recursively iterate over environments
find.by.address = function(addr, env = .GlobalEnv) {
  idx = which(sapply(ls(env), function(x) address(get(x, env = env))) == addr)
  if (length(idx) != 0)
    return (get(ls(env)[idx], env = env))

  # didn't find it, let's iterate over the other environments
  idx = which(sapply(ls(env), function(x) is.environment(get(x, env = env))))
  for (i in idx) {
    res = find.by.address(addr, get(ls(env)[i], env = env))
    if (res != "couldn't find it") return (res)
  }

  return ("couldn't find it")
}

DT = data.table(a = 1)
e = new.env()
e$DT = data.table(b = 2)
e$f = new.env()
e$f$DT = data.table(c = 2)

find.by.address(address(DT))
#   a
#1: 1
find.by.address(address(e$DT))
#   b
#1: 2
find.by.address(address(e$f$DT))
#   c
#1: 2
eddi
  • 49,088
  • 6
  • 104
  • 155
  • The most basic way how it could be done, somewhat silly but should work. Thanks for the answer. I need some time to test my cases (packages environments with child environments in them), and later accessed from GlobalEnv. Still looking for a straight solution without scanning all the R session. – jangorecki Apr 26 '15 at 18:01