2016-12-29 3 views
15

私はルビーフリーズ法を使用しています。凍結の定義が考慮される限り、それは呼び出されるオブジェクトの値をフリーズさせます。それ以降のオブジェクトの値は変更できません。私は、同じタスクを達成するために持っている私は、オブジェクトを持っていると私は、次のコード+ =演算子がフリーズした文字列を修正するようです

a = "Test" 
a.freeze 
a += "this string" 
puts a 

を実行していますこれは、次のように出力を与える:

Test this string 
[Finished in 0.0s] 

それは私の凍結された文字列を変更しているのはなぜ?

+3

可能な複製(http://stackoverflow.com/questions/17067171/freezing-variables-in-ruby- doesnt-work) – Manishh

+2

変数はさまざまです。それが彼らが変数と呼ばれる理由です。 –

+1

これは重複していることがわかりましたが、これは良い答えが付いたきれいな質問です。そのため、私はdupハンマーを使用することに躊躇しています。私はむしろ、この質問の重複として、[ノミネートされたexamplar](http://stackoverflow.com/questions/17067171/freezing-variables-in-ruby-doesnt-work)をマークしたいと思います。きれいではない。 –

答えて

46

何も

a = a + "this string" 

追加するときのようにRubyで内部的に同じである

a += "this string" 

で新しいStringにごフローズンString

あなたが再割り当てされているaを変更していませんRubyの2つのStringオブジェクトは、結果を含む新しいStringを作成します(これはの通常の動作ですオペレータは、それをサポートするほとんどのオブジェクト上にあります)。そのため、元の「テスト」と「この文字列」の値は変更されません。元の文字列( "Test"を含む)は、ガベージコレクトされるまでメモリに残ります。それはあなたがそれへのすべての参照を失ったので収集することができます。あなたはこのような場所でオブジェクトを変更しようとした場合

a << "this string" 

は、あなたはStringオブジェクトで、基本的に、あなたはaを混同しているRuntimeError: can't modify frozen String

エラーメッセージ、ローカル変数が表示されますそれが指しているのです。ローカル変数は、Rubyに格納されているオブジェクトとは無関係に、いつでも再割り当てできます。あなたの場合、a += ...行の前後にあるa.object_idを調べることで、これがあなたのケースで起こったことを確認できます。

+4

また注目に値する:前と後の 'a.object_id'は全く異なっています。これは、要素がクローンされた配列を持つ配列のように動作しているときに便利です*。 – tadman

2

フリーズメソッドは、オブジェクトを変更できないようにします。オブジェクトを定数に変換します。

s1 = "its testing" 
s1.freeze 
puts "Object ID ===", s1.obejct_id 

したがって、オブジェクトをフリーズした後で、オブジェクトをフリーズした後、そのオブジェクトを修正しようとすると、TypeErrorが発生します。

s1 << "testing again" 

それは、例外RuntimeErrorを与える:凍結された文字列に

を変更しかし、

凍結はない変数

s1 += "New Testing" 
puts "Object ID ===", s1.obejct_id 
に、 オブジェクト参照で動作することはできません

は新しいオブジェクトを評価し、そのオブジェクトIDもチェックするように指示します。このサイトを参照してください。詳細については

http://rubylearning.com/satishtalim/mutable_and_immutable_objects.html

[動作しませんRubyで変数を凍結]の
関連する問題