2014-06-05 59 views
2

未分配给任何变量/常量的对象立即消失(正常情况下)。在下文中,字符串"foo"不受ObjectSpace.each_object(String)在第三行捕获:收集不必分配给任何变量/常量的对象

strings = ObjectSpace.each_object(String).to_a 
    "foo" 
ObjectSpace.each_object(String).to_a - strings # => [] 

是否有可能捕获未necessarly分配给任何变量/常量的变量/常量或部分对象?我对捕获字符串特别感兴趣。相关的域可以是文件或块。我期望如下所示:

capture_all_strings do 
    ... 
    "a" 
    s = "b" 
    @s = "c" 
    @@s = "d" 
    S = "e" 
    %q{f} 
    ... 
end 
# => ["a", "b", "c", "d", "e", "f"] 
+0

只是'ObjectSpace.each_object(String).to_a'返回什么? – dax

+0

在这里有一个问题,字符串文字在编译时实例化。所以这就排除了一整套技巧,你可以通过修改'String.new'或类似的东西来将新对象添加到池中。 – amnn

+1

即使对象被分配给一个变量,它也不会被ObjectSpace.each_object(String)所捕获(例如,如果将第一个示例中的第二行更改为'a =“foo”'),那么看起来似乎从你的问题,这不是预期的行为,是吗? –

回答

1

Ruby在解析文件时创建字符串实例。这里有一个例子:字符串

"aaa #{123} zzz" 

被解析为:

$ ruby --dump=parsetree -e '"aaa #{123} zzz"' 
########################################################### 
## Do NOT use this node dump for any purpose other than ## 
## debug and research. Compatibility is not guaranteed. ## 
########################################################### 

# @ NODE_SCOPE (line: 1) 
# +- nd_tbl: (empty) 
# +- nd_args: 
# | (null node) 
# +- nd_body: 
#  @ NODE_DSTR (line: 1) 
#  +- nd_lit: "aaa " 
#  +- nd_next->nd_head: 
#  | @ NODE_EVSTR (line: 1) 
#  | +- nd_body: 
#  |  @ NODE_LIT (line: 1) 
#  |  +- nd_lit: 123 
#  +- nd_next->nd_next: 
#   @ NODE_ARRAY (line: 1) 
#   +- nd_alen: 1 
#   +- nd_head: 
#   | @ NODE_STR (line: 1) 
#   | +- nd_lit: " zzz" 
#   +- nd_next: 
#    (null node) 

有两个字符串文字在分析阶段,"aaa "" zzz"

#  +- nd_lit: "aaa " 
#  ... 
#   | +- nd_lit: " zzz" 

检查ObjectSpace证实,这些字符串已被实例化:

$ ruby -e '"aaa #{123} zzz"; ObjectSpace.each_object(String) { |s| p s }' | egrep "aaa|zzz" 
"\"aaa \#{123} zzz\"; ObjectSpace.each_object(String) { |s| p s }\n" 
"aaa 123 zzz" 
" zzz" 
"aaa " 

所以,除非你正在创建一个新的字符串实例(例如,通过将字符串文字分配给变量),您无法检测到字符串创建。代码执行时已经存在。

相关问题