2016-05-02 21 views

答えて

1

[...]文字列を変数に格納してフリーズすることはできません。

はほとんど、ルビーの最近のバージョンは、凍結された文字列を最適化することができます。

'foo'.freeze.object_id #=> 70313275108080 
'foo'.freeze.object_id #=> 70313275108080 

しかし、この最適化には限界があります。それは、文字列のために働くリテラル(上図のように)が、文字列が後に凍結されている場合、それは動作しません:

# frozen_string_literal: true 

puts 'foo'.object_id 
puts 'foo'.object_id 

出力:

a = 'foo' 
a.freeze 
a.object_id #=> 70313275335500 

b = 'foo' 
b.freeze 
b.object_id #=> 70313275274260 

あなたはfrozen_string_literal機能を有効にしない限り:

$ ruby test.rb 
70185151269500 
70185151269500 

または、コマンドラインから:

$ ruby --enable-frozen-string-literal -e "puts 'foo'.object_id, 'foo'.object_id" 
70102955495340 
70102955495340 
+0

どこで文字列を使用するのか、次にシンボルをどこで使用するのですか? –

+0

@RamziddinMakhmudovは、その内容が重要な場合、文字列を使用します。識別子またはラベルが必要な場合は、シンボルを使用します。 – Stefan

+0

清潔で分かりやすい回答ありがとうございます。) –

0

freezeは、実際のオブジェクトの変更を防止しますが、変数はオブジェクトへの参照であり、依然として参照を変更することができます。たとえば、以下は完全に有効です。

a = "foo" 
a.freeze 
a = "boo" 

aの最後は "boo"です。

Rubyバージョン2.1以前では、シンボルに利用可能なobject_idが割り当てられ、同じシンボル識別子が使用されるときはいつも同じobject_idが使用されます。これは決してガベージコレクションされません。これは不変ですが、より効率的です(メモリオーバヘッドが減ります)。

Rubyバージョン2.2以降では、シンボルはガベージコレクトされる点を除き、基本的に同じです。この変更の理由は、シンボルのDoS攻撃を防止するためでした。

+0

どこで文字列を使用し、どこでシンボルを使用するのですか? –

+0

ありがとうございました!私はシンボルのDoS攻撃について読むでしょう:) –

関連する問題