なぜ代入演算子の不在はありませんコンパイラの警告とRubyの定数を変更するために私を許可していますか?

StackOverflow https://stackoverflow.com/questions/670094

質問

次の2つの例では、私は一定の文字列を作成し、それを修正するためにconcatメソッドを使用して、同じことを行います。それは定数なので、私は、コンパイラの警告を期待するが、私は代入演算子を使用する場合のみ、第二の例では1を受け取ります。これはなぜでしょうか?

X = "hello"
X.concat(" world")
puts X # no warning

X = "hello"
X = X.concat(" world")
puts X # warning: already initialized
assigment演算子を使用する必要はありませんので、concatメソッドは、代わりに文字列を変更しているので、それは通常の

私は、どうなるのか。それでは、なぜ代入演算子の存在は、コンパイラが異なっているように、これらの2つの操作を特定するようにしますか?

役に立ちましたか?

解決

これは、あなたがしているので、あなたはそれがあなたに「すでに初期化」エラーを与える定数を再定義新しいXを再定義しています。あなたはそれを修正している、Xを再定義していないので、最初の例では、このエラーを与えるものではありません。

他のヒント

ないオブジェクト自体 -

Rubyでは、変数は、本質的にオブジェクトを含むメモリ内の場所へのポインタです。第二の例では、最初の行(X)内のオブジェクトを指すように定数X = "hello"を初期化され、2行目には、再度、一定の初期化されている - が、あなたが得るように、それは既に、オブジェクトを指し示しますエラーます。

定数の不変性は、あなたがオブジェクトを変更することはできませんという意味ではありません - それはちょうどあなたがの他のオブジェクトを指すように定数を変更することができないことを意味します。

あなたが一定のあなたの文字列が「本物」にしたい場合は、「凍結」を試してください:

X = "foo".freeze        # => "foo" 
X.concat("bar")

TypeError: can't modify frozen string
    from (irb):2:in `concat'
    from (irb):2

私は本当にのRubyプログラミングLanguge を読むことをお勧めします。

定数XStringオブジェクトへの参照を記憶しているためです。あなたの最初の例では、Stringオブジェクトの内部状態を変更しているが、参照が定数で保存されません。第二の例では、Stringメソッドから返された新しいconcatオブジェクトに定数によって記憶された基準を変更している。

つるはしブックはこちらのこのを説明します。

scroll top