Why does double shovel in Ruby not mutate state?

If we convert your a << b << c construct to a more method-ish form and throw in a bunch of implicit parentheses the behavior should be clearer. Rewriting:

greeting = "Hi there, " << name << "?"

yields:

greeting = ("Hi there, ".<<(name)).<<("?")

String#<< is modifying things but name never appears as the target/LHS of <<, the "Hi there ," << name string does but name doesn't. If you replace the first string literal with a variable:

hi_there = 'Hi there, '
greeting = hi_there << name << '?'
puts hi_there

you'll see that << changed hi_there; in your "Hi there, " case, this change was hidden because you were modifying something (a string literal) that you couldn't look at afterwards.


You are making it too complicated.

The operator returns the left-hand side and so in the first case it's just reading name (because "Hi there, " << name is evaluated first) but in the second example it is writing it.

Now, many Ruby operators are right-associative, but << is not one of them. See: https://stackoverflow.com/a/21060235/140740

Tags:

String

Ruby