6

I'm working through a tutorial right now, and I'd 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 += have no effect on original_string, and << does? I was absolutely certain that the second case would also equal "Hello, ", but that's not the case.

hi = original string in the first example appears to copy the value of original_string into hi, but hi = original string in the second example appears to set hi to point to the same string as original string. I would guess there is some kind of implicit decision behind the scenes as to whether to copy the value or copy the reference... or something.

user513951
  • 12,445
  • 7
  • 65
  • 82
CptSupermrkt
  • 6,844
  • 12
  • 56
  • 87

3 Answers3

3

<< on string mutates the original object while += creates a copy and returns that.

See the object_id of the respective strings 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 

Note the different object_id on hi on line 35. Once you reset hi to original_string in your example above, and use <<, it modifies the same object.

CDub
  • 13,146
  • 4
  • 51
  • 68
3

In both examples, hi = original_string copies the reference.

With +=, however, you reassign hi to point to a new string, even though the variable name is the same.

This is because hi += there expands in the interpreter to the expression hi = hi + there.

Before this operation, hi and original string share a reference to the same string object. Upon the = operation in the expanded expression, hi now references the newly-created string result of hi + there.

In the expression hi << there, nothing happens to change which object hi refers to. It refers to the same string as original_string, and therefore both hi and original_string reflect the change (which is of course due to the fact that they both reference the same string object).

user513951
  • 12,445
  • 7
  • 65
  • 82
1

You should check out the Ruby documentation for the String Class:

String#+ method

String#<< method

Greg Burghardt
  • 17,900
  • 9
  • 49
  • 92