Try this:
class Klass
attr_accessor :name
end
a = Klass.new
a.name = Klass.new #object inside object
a.name.name = 'George'
b = a.dup
puts b.name.name # George
b.name.name = 'Alex'
puts a.name.name # Alex
Also note that (see info):
When using dup, any modules that the object has been extended with
will not be copied.
Edit: Note on Strings (this was interesting to find out)
Strings are referenced not copied in the original scenario. This is proven through this case:
a.name = 'George'
puts a.name.object_id # 69918291262760
b = a.dup
puts b.name # George
puts b.name.object_id # 69918291262760
b.name.concat ' likes tomatoes' # append to existing string
puts b.name.object_id # 69918291262760
puts a.name # George likes tomatoes
This works as expected. Referenced objects (including strings) are not copied, and will share the reference.
So why does the original example appear not too? It is because when you set b.name to a something different you are setting it to a new string.
a.name = 'hello'
is really short hand for this:
a.name = String.new('hello')
Therefore in the original example, a.name & b.name are no longer referencing the same object, you can check the object_id to see.
Note that is not the case for Fixnum, floats, true, false or symbols. These objects are duplicated in a shallow copy.