为什么`ObjectSpace.each_object(String)`包含任何字符串?

时间:2014-06-05 15:47:54

标签: ruby objectspace

在Mike H-R和Stefan对a question of mine的评论之后,我注意到ObjectSpace.each_object(String)包含了我能想到的任何字符串:

strings = ObjectSpace.each_object(String)
strings.include?("some random string") # => true

strings = ObjectSpace.each_object(String).to_a
strings.include?("some random string") # => true

我认为strings应该只包含此时存在的字符串。为什么它包含任何字符串?

然而,当我计算strings的长度时,它会返回一个有限数字:

ObjectSpace.each_object(String).to_a.length # => 15780

这可以在Ruby 2.1.2p95(2014-05-08修订版45877)[x86_64-linux]解释器和irb上观察到。

这与Ruby 2.1中引入的冻结字符串文字优化有什么关系吗?

2 个答案:

答案 0 :(得分:5)

IRB 字符串中编写代码时,在ObjectSpace输入代码时会添加:

strings = ObjectSpace.each_object(String)
strings.include?("some random string") # => true

strings = ObjectSpace.each_object(String).to_a
strings.include?("some other random string") # => false

rb文件中尝试时,文本已经存在,因为在解析文件时添加了

<强> test.rb

strings = ObjectSpace.each_object(String)
strings.include?("some random string") # => true

strings = ObjectSpace.each_object(String).to_a
strings.include?("some other random string") # => true

strings = ObjectSpace.each_object(String).to_a
strings.include?("some other random string " + "dynamically built") # => false

答案 1 :(得分:0)

那是因为为了将“一些随机字符串”传递给include?的{​​{1}}迭代器上的ObjectSpace方法,你必须首先创建字符串“some random string”。

简单地通过询问each_object是否存在“某个随机字符串”,您正在创建“一些随机字符串”,因此它当然存在于对象空间中。看看我在说什么?这就解释了你的第一个例子。

在你的第二个例子中,当你在引用“一些随机字符串”之前得到字符串对象的数组时,你会认为你会变错。正如你所指出的那样,情况并非如此。我假设这是因为你使用的是字符串文字,而Ruby正在通过在实际引用字符串之前创建字符串来优化代码。我对Ruby的内部结构了解不多,但是我还要详细说明。