You're doing two very different things.
Your "primitive variable" example:
a = 'b'
d = a
a = 'c'
is a simple assignment so that at the end of line 2, a
and d
refer to the same object. Then on line 3, a
is assigned a new object and a
and d
end up referring to different objects.
Your first example:
a = {b: 'c'}
d = a
a[:b] = 'qwerty'
is an assignment followed by a call to a method that mutates its receiver. The third line could also be written as one of the following that make the the method call more explicit:
a.[]=(:b, 'qwerty')
a.send(:[]=, :b, 'qwerty')
So you're comparing an assignment by a mutating method call with a series of assignments.
If your second example used a mutator method on a
:
a = 'b'
# => 'b'
d = a
# => 'b'
a[0] = 'c' # String#[]= alters its receiver
# => 'c'
d
# => 'c'
then both a
and d
would change because you're not doing an assignment to change the object that a
refers to, you're changing the referred object.
This question isn't quite a duplicate of Is Ruby pass by reference or by value?, close but not quite. I'm sure this is a duplicate of several other questions but I can't find them right now. If someone finds a proper duplicate, let me know and I'll delete this and pull out my dupe-hammer.