Why does `<<` append to the Ruby string, but `+ =` doesn't?

I am currently studying a textbook, and I would like to understand why the following occurs:

 original_string = "Hello, " hi = original_string there = "World" hi += there assert_equal "Hello, ", original_string original_string = "Hello, " hi = original_string there = "World" hi << there assert_equal "Hello, World", original_string 

Why does += not affect original_string , but << does? I was absolutely sure that the second case would also be equal to "Hello, " but this is not so.

hi = original string in the first example appears to copy the value of original_string to hi , but hi = original string in the second example indicates that hi points to the same string as the original string . I would suggest that behind the curtains there is some implicit decision about whether to copy the value or copy the link ... or something like that.

+6
source share
3 answers

<< in the string mutates the original object, and += creates a copy and returns this.

See object_id relevant lines below:

 2.1.1 :029 > original_string = "Hello, " => "Hello, " 2.1.1 :030 > hi = original_string => "Hello, " 2.1.1 :031 > there = "World" => "World" 2.1.1 :032 > original_string.object_id => 70242326713680 2.1.1 :033 > hi.object_id => 70242326713680 2.1.1 :034 > hi += there => "Hello, World" 2.1.1 :035 > hi.object_id => 70242325614780 

Notice the different object_id on hi in line 35. After you reset hi to original_string in the above example and use << , it changes the same object.

+3
source

In both examples, hi = original_string copies the link.

With += , however, you reassign hi to point to a new line, although the variable name is the same.

This is due to the fact that hi += there expands in the interpreter to the expression hi = hi + there .

Prior to this operation, hi and original string use a link to the same string object. After the = operation, in the extended expression, hi now refers to the newly created result of the string hi + there .

In the expression hi << there will not change anything to which object hi belongs. It refers to the same string as original_string , and therefore both hi and original_string reflect the change (which, of course, is due to the fact that both of them refer to the same string object).

+3
source

You should check the Ruby documentation for the String class:

String # + method

String # <<<<Method

+1
source

All Articles