2

在 Mike HR 和 Stefan 对我的一个问题发表评论后,我注意到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 中引入的冻结字符串文字优化有什么关系?

4

2 回答 2

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文件中执行此操作时,文本已经存在,因为它是在解析文件时添加的

测试.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
于 2014-06-05T15:58:21.187 回答
0

那是因为为了将“一些随机字符串”传递给's迭代器include?上的方法,您必须首先创建字符串“一些随机字符串”。ObjectSpaceeach_object

仅仅通过询问ObjectSpace“一些随机字符串”的存在,你正在创建“一些随机字符串”,所以它当然存在于对象空间中。明白我在说什么吗?这解释了你的第一个例子。

在第二个示例中,当您在引用“一些随机字符串”之前获取字符串对象数组时,您会认为您会得到错误。正如你所指出的,情况并非如此。我认为这是因为您使用的是字符串文字,而 Ruby 正在通过在您实际引用它之前创建字符串来优化您的代码。我对 Ruby 的内部结构知之甚少,无法详细说明。

于 2014-06-05T16:13:01.267 回答