Reputation: 8945
I am having some trouble understanding the concept of a shallow copy and the #dup
method
I have this code
class MyObject
end
myObject1 = MyObject.new
myObject2 = MyObject.new
I know this will print false becuase I am testing for object equality, not value equality
p myObject1 == myObject2
But according to the definition of a shallow copy
.dup produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference.
I had expected this to print true, but it also prints false
p myObject1 == myObject1.dup
Isn't the definition wrong then? Shouldn't myObject1.dup
an instance variable
that points to the same object as myObject1
, except it's clearly not?
Upvotes: 0
Views: 152
Reputation: 434665
You forget that ==
is actually a method from BasicObject
:
obj == other → true or false
Equality — At the Object level,==
returnstrue
only ifobj
and other are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning.
So if you haven't provided your own implementation of ==
(i.e. a MyObject#==
method) then your:
p myObject1 == myObject1.dup
is pretty much the same as saying:
p myObject1.object_id == myObject1.dup.object_id
and since myObject1.dup
is a shallow copy of myObject1
(i.e. they're different objects), you get false
.
When they say:
instance variables of
obj
are copied
they're referring to the instance variables inside obj
, not variables that happen to reference obj
. Your myObject1
isn't an instance variable in anything, it is just a variable, instance variables are referenced with a leading @
as in @my_instance_variable
.
If you want ==
to behave they way you expect it to then you have to provide your own ==
implementation:
class MyObject
def ==(other)
# Check that the contents of `self` and `other` are the same
# and probably that `other.is_a?(MyObject)` first.
end
end
Upvotes: 1