什么时候声明为冻结的String被分配(如果有的话?)

时间:2015-10-05 19:30:47

标签: ruby string string-interning

在ruby 2.2中,执行以下操作分配新的String对象或使用已被实例化的对象?假设这些命令按照它们的顺序运行。

"foo".freeze
foo = "foo".freeze
foo2 = "foo"
foo2.freeze
foo3 = foo.freeze
foo4 = ["foo".freeze].first
foo5 = ["foo"].map(&:freeze).first

如果你能提供你的答案证明,那也很棒。)。

3 个答案:

答案 0 :(得分:1)

  

在Ruby 2.1中,“str”.freeze由编译器优化以返回a   每次调用时都有一个共享的冻结字符串。

来自:http://tmm1.net/ruby21-fstrings/

您可以使用if ($images = scandir('path_to_your_image_directory')) { foreach ($images as $image) { print '<a href="$image">$image.jpg</a>'; // Might need to preface the $image variable with path to your image directory } } 方法自行测试。

object_id

答案 1 :(得分:1)

"foo".freeze.object_id              # => 70148079771220
foo = "foo".freeze
foo.object_id                       # => 70148079771220
foo2 = "foo"
foo2.object_id                      # => 70148076813240
foo2.freeze
foo2.object_id                      # => 70148076813240
foo3 = foo.freeze
foo3.object_id                      # => 70148079771220
foo4 = ["foo".freeze].first
foo4.object_id                      # => 70148079771220
foo5 = ["foo"].map(&:freeze).first
foo5.object_id                      # => 70148079700740

基本上,你可以通过两条规则来理顺它:

  • 调用String#freeze不会更改已引用字符串的对象ID。
  • 在文字字符串上调用String#freeze将引用内化版本。

答案 2 :(得分:1)

不幸的是,这很难说。 YARV 2.1+ 确实执行一些字符串实习优化,但是,不清楚这些优化是YARV 2.1+的私有内部实现细节还是Ruby 2.1+语义的官方保证特性,即部分Ruby 2.1+语言规范。问题是:没有&#34; Ruby 2.1+语言规范&#34;在matz的头脑之外,所以没有地方可以找到答案。

它们在YARV 2.1的ChangeLog中有描述,但同样,这并没有多说:ChangeLog自由地将YARV的功能与Ruby的功能混合在一起,而没有指出哪个是哪个。