36

Are Strings mutable in Ruby? According to the documentation doing

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

creates a new string object with the value "hello world" but when we do

str = "hello"
str << " world"

It does not mention that it creates a new object, so does it mutate the str object, which will now have the value "hello world"?

user513951
  • 12,445
  • 7
  • 65
  • 82
Aly
  • 15,865
  • 47
  • 119
  • 191

3 Answers3

74

Yes, << mutates the same object, and + creates a new one. Demonstration:

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>
lulalala
  • 17,572
  • 15
  • 110
  • 169
Dogbert
  • 212,659
  • 41
  • 396
  • 397
8

Just to complement, one implication of this mutability is seem below:

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" 

and

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" 

So, you should choose wisely the methods you use with strings in order to avoid unexpected behavior.

Also, if you want something immutable and unique throughout your application you should go with symbols:

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 
Pablo B.
  • 1,823
  • 1
  • 17
  • 27
0

While above answers are perfect, Just adding this answer for future readers.

In most languages, string literals are also immutable, just like numbers and symbols. In Ruby versions that are less than 3, all strings are mutable by default. This changed in Ruby 3. Now all string literals are immutable by default in Ruby 3++ versions.

Umar Tahir
  • 585
  • 6
  • 21