1

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

あなたの答えの証拠を提供できれば、それも素晴らしいでしょう:)。

4

3 に答える 3

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

したがって、基本的には、次の 2 つのルールで合理化できます。

  • 呼び出しString#freezeても、既に参照されている文字列のオブジェクト ID は変更されません。
  • リテラル文字列を呼び出すString#freezeと、内部化されたバージョンが参照されます。
于 2015-10-05T19:41:37.857 に答える
1

残念ながら、これを言うのは本当に難しいです。YARV 2.1+いくつかの文字列インターンの最適化を実行しますが、それらの最適化が YARV 2.1+ のプライベートな内部実装の詳細なのか、Ruby 2.1+ セマンティクスの公式に保証された機能、つまり Ruby 2.1+ 言語仕様の一部なのかは明らかではありません。問題は、matz の頭の外に「Ruby 2.1+ 言語仕様」がないため、答えを探す場所がないことです

それらは YARV 2.1 の ChangeLog に記述されていますが、これもあまり多くはありません。ChangeLog は、どちらがどちらであるかを示すことなく、YARV の機能と Ruby の機能を自由に組み合わせています。

于 2015-10-06T01:37:26.583 に答える
1

Ruby 2.1 では、"str".freeze はコンパイラによって最適化され、すべての呼び出しで単一の共有凍結文字列が返されます。

出典: http://tmm1.net/ruby21-fstrings/

メソッドを使用して、object_idこれを自分でテストできます。

"foo".freeze.object_id
=> 87323600

foo = "foo".freeze
foo.object_id
=> 87323600
于 2015-10-05T19:39:45.827 に答える