在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中引入的冻结字符串文字优化有什么关系吗?
答案 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的内部结构了解不多,但是我还要详细说明。