A few days ago I started solving the Ruby Koans, which is an amazing way to learn Ruby by solving problems (I highly recommend anyone interested in Ruby to check it out). It is basically a set of Ruby files with a series of errors (intentionally made) that you have to fix for the code to execute.
One of the steps of the Ruby Koans (step 57 to be exact, method test_the_shovel_operator_will_also_append_content_to_a_string
) helped me to understand the difference between the plus-equal (+=) and the shovel (<<) operators. I decided to write this post to explain it. For the sake of readability and compactness, I’ll omit the irb output when desirable. Consider the following variables:
>> a="foo" >> b="bar" >> a_=a
Suppose we want to concatenate the strings a_
and b
, and store the resulting value in the variable a_
itself. We could use the plus-equal operator to accomplish that:
>> a_ += b
The plus-equal operator concatenates the strings a_
and b
, and stores the resulting value in the variable a_
. Let’s check the value of the three strings after the operation:
>> a => "foo" >> b => "bar" >> a_ => "foobar"
As you can see, the variable a_
stores the concatenated string. The values of a
and b
are still the original values.
Now let’s reinitialize our variables and check the results obtained with the shovel operator:
>> a="foo" >> b="bar" >> a_=a
>> a_ << b
>> a.to_s => "foobar" >> b.to_s => "bar" >> a_.to_s => "foobar"
Surprisingly, the string stored in the variable a
changed after we used the shovel operator. This side-effect is the difference between the two operators. In ruby, when one variable is assigned to another (like in a_=a
), both of them will point to the same object (will have the same object id).
>> a="foo" >> a_=a >> a.object_id => 2230175300 >> a_.object_id => 2230175300
When the plus-equal operator is used, a new string is created and assigned to the variable a_
(a new reference), thus keeping the string stored in the variable a
unmodified.
The shovel operator, on the other hand, updates the value of the object referenced by a_
, but not the reference itself. Since both variables (a
and a_
) reference the same object, the value of a
will be changed when using the shovel operator.