Search code examples
rubyobjectspace

Why does `ObjectSpace.each_object(String)` include just about any string?


After comments by Mike H-R and Stefan to a question of mine, I noticed that ObjectSpace.each_object(String) includes just about any string I can think of:

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

or

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

I thought that strings should include only strings that existed at that point. Why does it include just about any string?

Yet, when I count the length of strings, it returns a finite number:

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

This is observed on Ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux] interpreter and irb.

Does this have anything to do with frozen string literal optimization introduced in Ruby 2.1?


Solution

  • When writing code in the IRB strings are added to the ObjectSpace as they are typed:

    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
    

    When trying to do it inside an rb file, the text is already there, because it is added when the file is parsed.

    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