1. 字符串
当我有一个非卡住非实习字符串时,我可以获得它的源位置(假设文件名是 foo_file.rb
):
require "objspace"
ObjectSpace.trace_object_allocations_start
obj = "foo"
ObjectSpace.allocation_sourcefile(obj) # => foo_file.rb
ObjectSpace.allocation_sourceline(obj) # => 4
当我有一个实习字符串时,源位置变得不可用(注意字符串文字后带有 freeze
的实习功能):obj = "foo".freeze
ObjectSpace.allocation_sourcefile(obj) # => nil
ObjectSpace.allocation_sourceline(obj) # => nil
我可以确认这种不可用不是因为它被卡住,而是因为它被实习:obj = "foo"
obj = obj.freeze
ObjectSpace.allocation_sourcefile(obj) # => foo_file.rb
ObjectSpace.allocation_sourceline(obj) # => 4
为什么我不能从一个实习字符串中获取源信息?2. 正则表达式
当我有一个正则表达式时,即使它没有被卡住,我也无法获取源信息:
obj = /foo/
obj.frozen? # => false
ObjectSpace.allocation_sourcefile(obj) # => nil
ObjectSpace.allocation_sourceline(obj) # => nil
为什么即使没有卡住,我也无法从正则表达式中获取源位置? 最佳答案
这两个对象只是在 ObjectSpace.trace_object_allocations_start
调用或此文件中的任何其他 Ruby 代码执行之前分配的:
"foo".freeze
被分配在 compile time by rb_fstring()
(最初也在 parse time ) "foo"
在运行时的额外分配发生只是因为内部 obj = "foo"
实际上类似于 obj = "foo".dup
。有关更多详细信息,请查看 putstring
YARV instruction 和 rb_str_resurrect()
函数的定义。 /foo/
在 parse time by reg_compile()
分配。就是这样。这里没有重复,所以它总是同一个对象(虽然没有发生实习,但对某些人来说这可能是令人惊讶的行为):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]
关于ruby - 为什么我无法获取分配源信息?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35467521/