web-dev-qa-db-ja.com

Rubyで文字列は変更可能ですか?

Rubyで文字列は変更可能ですか? documentation によると

str = "hello"
str = str + " world"

"hello world"という値で新しい文字列オブジェクトを作成しますが、

str = "hello"
str << " world"

新しいオブジェクトを作成することについては触れていないので、strオブジェクトを変更します。これにより、値は"hello world"になります。

33
Aly

はい、 <<は同じオブジェクトを変更し、+は新しいものを作成します。デモンストレーション:

irb(main):011:0> str = "hello"
=> "hello"
irb(main):012:0> str.object_id
=> 22269036
irb(main):013:0> str << " world"
=> "hello world"
irb(main):014:0> str.object_id
=> 22269036
irb(main):015:0> str = str + " world"
=> "hello world world"
irb(main):016:0> str.object_id
=> 21462360
irb(main):017:0>
66
Dogbert

補足として、この可変性の影響の1つを以下に示します。

Ruby-1.9.2-p0 :001 > str = "foo"
 => "foo" 
Ruby-1.9.2-p0 :002 > ref = str
 => "foo" 
Ruby-1.9.2-p0 :003 > str = str + "bar"
 => "foobar" 
Ruby-1.9.2-p0 :004 > str
 => "foobar" 
Ruby-1.9.2-p0 :005 > ref
 => "foo" 

そして

Ruby-1.9.2-p0 :001 > str = "foo"
 => "foo" 
Ruby-1.9.2-p0 :002 > ref = str
 => "foo" 
Ruby-1.9.2-p0 :003 > str << "bar"
 => "foobar" 
Ruby-1.9.2-p0 :004 > str
 => "foobar" 
Ruby-1.9.2-p0 :005 > ref
 => "foobar" 

したがって、予期しない動作を回避するために、文字列で使用するメソッドを賢く選択する必要があります。

また、アプリケーション全体で不変でユニークなものが必要な場合は、シンボルを使用する必要があります。

Ruby-1.9.2-p0 :001 > "foo" == "foo"
 => true 
Ruby-1.9.2-p0 :002 > "foo".object_id == "foo".object_id
 => false 
Ruby-1.9.2-p0 :003 > :foo == :foo
 => true 
Ruby-1.9.2-p0 :004 > :foo.object_id == :foo.object_id
 => true 
8
Pablo B.