Reputation: 168101
When I have a non-frozen non-interned string, I can get its source location (suppose the file name is foo_file.rb
):
require "objspace"
ObjectSpace.trace_object_allocations_start
obj = "foo"
ObjectSpace.allocation_sourcefile(obj) # => foo_file.rb
ObjectSpace.allocation_sourceline(obj) # => 4
When I have an interned string, the source location becomes unavailable (note the interning feature with freeze
after a string literal):
obj = "foo".freeze
ObjectSpace.allocation_sourcefile(obj) # => nil
ObjectSpace.allocation_sourceline(obj) # => nil
I can confirm that this unavailability is not because it is frozen, but it is because it is interned:
obj = "foo"
obj = obj.freeze
ObjectSpace.allocation_sourcefile(obj) # => foo_file.rb
ObjectSpace.allocation_sourceline(obj) # => 4
Why can't I get the source information from an interned string?
When I have a regex, I can't get the source information even if it is not frozen:
obj = /foo/
obj.frozen? # => false
ObjectSpace.allocation_sourcefile(obj) # => nil
ObjectSpace.allocation_sourceline(obj) # => nil
Why can't I get the source location from a regex even when it is not frozen?
Upvotes: 3
Views: 86
Reputation: 4927
Those two objects were simply allocated before the ObjectSpace.trace_object_allocations_start
call or any other Ruby code in this file was executed:
"foo".freeze
was allocated at compile time by rb_fstring()
(and originally also at parse time)
the additional allocation of "foo"
at run time happens only because internally obj = "foo"
is actually similar to obj = "foo".dup
. Take a look at the definition of the putstring
YARV instruction and the rb_str_resurrect()
function for more details.
/foo/
was allocated at parse time by reg_compile()
. That's it. No duplication here, so it's always the same object (no interning occurs though and it might be surprising behavior to some):
3.times.map{ "foo".object_id }.uniq # => [21063740, 21063720, 21063700]
3.times.map{ "foo".freeze.object_id }.uniq # => [21064340]
3.times.map{ /foo/.object_id }.uniq # => [21065100]
Upvotes: 2