次のコードについて考えてみます。
$ irb
> s = "asd"
> s.object_id # prints 2171223360
> s[0] = ?z # s is now "zsd"
> s.object_id # prints 2171223360 (same as before)
> s += "hello" # s is now "zsdhello"
> s.object_id # prints 2171224560 (now it's different)
新しい文字列を作成せずに、個々の文字を変更できるようです。ただし、文字列に追加すると、明らかに新しい文字列が作成されます。
文字列はRuby可変ですか?
はい、Pythonとは異なり、Rubyの文字列は変更可能です。
s += "hello"
はnot"hello"
をs
に追加します-まったく新しい文字列オブジェクトが作成されます。文字列「インプレース」に追加するには、次のように<<
を使用します。
s = "hello"
s << " world"
s # hello world
Ruby-1.9.3-p0 :026 > s="foo"
=> "foo"
Ruby-1.9.3-p0 :027 > s.object_id
=> 70120944881780
Ruby-1.9.3-p0 :028 > s<<"bar"
=> "foobar"
Ruby-1.9.3-p0 :029 > s.object_id
=> 70120944881780
Ruby-1.9.3-p0 :031 > s+="xxx"
=> "foobarxxx"
Ruby-1.9.3-p0 :032 > s.object_id
=> 70120961479860
したがって、文字列は変更可能ですが、+=
演算子は新しい文字列を作成します。 <<
古いまま
Ruby String に追加するのは+=
ではなく、<<
です。
したがって、+=
を<<
に変更すると、質問は自動的に解決されます
Rubyの文字列は変更可能ですが、フリーズして変更できます。
irb(main):001:0> s = "foo".freeze
=> "foo"
irb(main):002:0> s << "bar"
RuntimeError: can't modify frozen String
Ruby文字列は変更可能です。ただし、連結には+ではなく<<を使用する必要があります。
実際、文字列をと連結する
+ operator(immutable)新しい文字列オブジェクトを作成するため。
<< operator(mutable)同じオブジェクト内で変更されるため。
このプルリクエスト で作成できることから、Ruby 3.0では、すべての文字列を作成する「魔法のコメント」を追加できるようになります不変 、変更可能ではなく。
このコメントを明示的に追加する必要があるように思われるため、「文字列は変更可能ですデフォルト?」という答えのようです。それでも「はい」になりますが、一種の条件付き「はい」は、スクリプトに魔法のコメントを書き込んだかどうかによって異なります。
[〜#〜]編集[〜#〜]
私はこれを指摘しました Ruby-Lang.orgのバグ/問題 これはsome Ruby3.0の文字列のタイプは実際には不変であると明確に述べていますデフォルトでは。