我破解了它,虽然我不明白我所做的一切。
我注意到pryr::address 给出的结果与tracemem 不同,并尝试了它(我必须深入研究代码才能使用pryr:::address2,因为pryr::address 没有环境参数)。
然后我注意到,将 x 上的 tracemem 和 pryr:::address2 的结果混合在其余对象上,有一个匹配项(在基本重新格式化之后):
`(<-` <- function(x,value){
pf <- parent.frame()
all_addresses <- sapply(ls(pf), pryr:::address2, pf)
all_addresses <- all_addresses[names(all_addresses) != "*tmp*"]
all_addresses_short <- gsub("(^|<)[0x]*(.*?)(>|$)","\\2",all_addresses)
x_address <- tracemem(x)
x_address_short <- tolower(gsub("(^|<)[0x]*(.*?)(>|$)","\\2",x_address))
ind <- match(x_address_short, all_addresses_short)
x_name <- names(all_addresses)[ind]
message("all_addresses, using pryr::address2")
print(all_addresses)
print(all_addresses_short)
message("x_address, using tracemem")
print(x_address)
print(x_address_short)
message("x_name, matching substrings")
print(x_name)
value
}
gsub 调用中使用的正则表达式试图解释我们在不同系统中获得的地址格式,我不能 100% 确定它是通用的。
输出:
foo <- 1
bar <- 2
(foo) <- foo
# all_addresses, using pryr::address2
# (<- bar foo
# "0x1433df50" "0x14937678" "0x14937708"
# (<- bar foo
# "1433df50" "14937678" "14937708"
# x_address, using tracemem
# [1] "<0000000014937708>"
# [1] "14937708"
# x_name, matching substrings
# [1] "foo"
如果 x 不是变量名则中断,例如:
foo <- iris
(foo$species) <- 3
我们可以假设如果找不到地址 x 是一个列表项,然后在 parent.frame 中的所有列表项的地址中查找它的地址(递归),但我认为这是今天的丑陋技巧已经够多了。