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