【问题标题】:Why does `ObjectSpace.each_object(String)` include just about any string?为什么 `ObjectSpace.each_object(String)` 包含几乎所有字符串?
【发布时间】:2014-06-05 15:47:54
【问题描述】:

在 Mike H-R 和 Stefan 到 a question of mine 的 cmet 之后,我注意到 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 中引入的冻结字符串文字优化有关?

【问题讨论】:

  • 在引入"some random string" 之前运行strings = ObjectSpace.each_object(String).to_a 导致false...

标签: ruby objectspace


【解决方案1】:

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

【讨论】:

  • 这似乎与您对我的问题的评论相矛盾。
  • 我在irb 中尝试过,这是答案的第一部分。当我将它放入 test.rb 并运行它时,行为是不同的
  • 您是否声称ObjectSpace.each_object 在执行脚本之前在解析后保持状态?
  • 我通过行为得出结论,我看到加载的 ruby​​ 文件中的文字字符串在其代码运行之前被加载到 ObjectSpace
  • 我很确定 IRB 在你输入之前不会将字符串添加到ObjectSpace ;)
【解决方案2】:

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

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

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

【讨论】:

  • 这可能适用于我没有to_a 的第一个示例,但不适用于我使用to_a 的第二个示例。
猜你喜欢
  • 1970-01-01
  • 2018-11-22
  • 2021-04-14
  • 2012-12-16
  • 2012-02-04
  • 1970-01-01
  • 2011-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多