1
irb(main):009:0> a = "good"
=> "good"
irb(main):010:0> a = "good" + "morning"
=> "goodmorning"
irb(main):011:0> a = "good"
=> "good"
irb(main):012:0> a << " morning"
=> "good morning"

今のところ、両方のconcatenationオペレーターが正常に動作しています。

irb(main):013:0> a = "good"
=> "good"

irb(main):014:0> a.freeze
=> "good"

irb(main):015:0> a.frozen?
=> true

irb(main):016:0> a << " welcome"
RuntimeError: can't modify frozen String
    from (irb):16
    from /usr/bin/irb:12:in `<main>'


irb(main):017:0> a = a +  " welcome"
=> "good welcome"

しかし、文字列を使用すると、それとfrozenの違いがはっきりとわかり、想定どおりに動作していません。誰かがこの理由を教えてもらえますか?IRB<<+

4

3 に答える 3

5

彼らはまさに彼らがすべきことをやっています。は呼び出された文字列<< を変更+しますが、は に近いstr.dup << argです。この動作は、定義され、文書化された標準です。

于 2013-02-16T18:16:51.747 に答える
1

@Linuxiosの答えは完璧です。

しかし、ここでも、より透過的な方法でその変更を表示しようとしました。

@ubuntu:~$ irb --simple-prompt
>> a = "good"
=> "good"

>> a.freeze
=> "good"

>> a.frozen?
=> true

>> a.object_id
=> 10557720 # holds the reference to the "good" string object.

>> a = a + " morning"
=> "good morning"

>> a.object_id
=> 10415700 # holds the reference to the new string object "good morning". 

>> a.frozen?
=> false

>> ObjectSpace._id2ref(10415700)
=> "good morning"
>> ObjectSpace._id2ref(10557720)
=> "good"
>> ObjectSpace._id2ref(10557720).frozen?
=> true

そうです、文字列「良い」はまだ凍結されていると結論付けることができます。起こったことはa、新しいオブジェクト「おはよう」を参照することだけです。への参照割り当てのみaが変更されました。

于 2013-02-16T19:23:24.237 に答える