1

Until v3.5 (I think), R had a poor-man's reference count facility called NAMED. In a nutshell, an object's NAMED attributed can hold 3 values:

  • 0 - the object is not named (i.e., not referenced and can be garbage collected)
  • 1 - the object is referenced by a single name (and so can be modified in place)
  • 2 - a.k.a "many": the object is referenced by many names. If it changes - needs to be copied. If a name is removed the NAMED attribute would not decrement.

(some more details here).

I'm trying to view this attribute from R, and am experimenting both with pryr::refs(x) and .Internal(inspect(x)). I can't understand the results of either.

tst <- function(x) {
  print(pryr::refs(x))   # 0
  .Internal(inspect(x))  # 2

  x[5] <- as.integer(14)
  print(pryr::refs(x))   # 1
  .Internal(inspect(x))  # 1

  y<-x
  print(pryr::refs(x))   # 2
  .Internal(inspect(x))  # 2
}
a <- 1:100
tst(a)

# [1] 0
# @5646a302a020 13 INTSXP g0c7 [NAM(2)] (len=100, tl=0) 1,2,3,4,5,...
# [1] 1
# @5646ab296810 13 INTSXP g0c7 [NAM(1)] (len=100, tl=0) 1,2,3,4,14,...
# [1] 2
# @5646ab296810 13 INTSXP g0c7 [NAM(2)] (len=100, tl=0) 1,2,3,4,14,...

Can anyone shed some light on what's going on here? Is there a better way to inspect an object's references?

Ofek Shilon
  • 14,734
  • 5
  • 67
  • 101
  • 1
    I have ended up in this thread a couple of times: [Confused about NAMED](https://stat.ethz.ch/pipermail/r-devel/2011-November/thread.html#62653). Perhaps you find something useful there. I try to remember some blog post (or was it SO?) on the topic...I come back if my brain starts working. – Henrik Aug 20 '20 at 14:52
  • A little more in [Hadley's book](http://adv-r.had.co.nz/memory.html#modification). I note that he refers to the "Confused" thread... – Henrik Aug 20 '20 at 14:57
  • Don't know if you use RStudio, but it has caused some extra confusion previously in relation to NAM: [Operator “[<-” in RStudio and R](https://stackoverflow.com/questions/15559387/operator-in-rstudio-and-r) (and linked therein, e.g. [Why is a length one vector initially at NAM(2)?](https://stackoverflow.com/questions/22022772/why-is-a-length-one-vector-initially-at-nam2)). Finally, I think you would help potential helpers if you could formulate a more specific question. Cheers. – Henrik Aug 20 '20 at 15:16
  • 2
    If _the_ Matt Dowle writes "Confused about NAMED" and Peter Dalgaard from the R core team answers "_This is tricky business... I'm not quite sure I'll get it right, but let's try_", I think it's perfectly fine to be confused. – Henrik Aug 20 '20 at 15:22
  • @Henrik I tested the toy code both on rstudio and raw r console, the results are identical. – Ofek Shilon Aug 20 '20 at 15:56
  • @Henrik I get that it’s complicated and am willing to give up on understanding the reasons for the values... but can you say why pryr::refs is different from inspect on the argument before modification? – Ofek Shilon Aug 20 '20 at 17:52
  • @OfekShilon This post may be helpful: [Why is the address of a loop variable changing when using it?](https://stackoverflow.com/questions/39746551/why-is-the-address-of-a-loop-variable-changing-when-using-it), including comments [here](https://stackoverflow.com/questions/39746551/why-is-the-address-of-a-loop-variable-changing-when-using-it#comment66789851_39746551) and [here](https://stackoverflow.com/questions/39746551/why-is-the-address-of-a-loop-variable-changing-when-using-it#comment66790385_39746551) – Henrik Aug 21 '20 at 11:57
  • @Henrik I changed the order of `pryr::refs` and `inspect`, and the results persist. (0 shown by `refs`, 2 by `inspect`). So the reason for the diff is probably not any increment by one of the functions themselves. – Ofek Shilon Aug 21 '20 at 18:06
  • 2
    `pryr::refs` first calls `Rf_findVar` on the symbol, whereas `inspect` directly acts on the object. It's not clear why pryr insists on first working on the symbol. Even if `pryr:refs` modified NAMED/REFCNT, it would still be at least 1. At any rate it looks like a bug and doesn't find the correct object. The right answer is "2 1 2". Since there is no decrement of REFCNT, this works exactly the same way in R 4.0 -- in R 4.0, `pryr::refs` aligns with `inspect`. – thc Dec 21 '20 at 09:24

0 Answers0