the_prole
the_prole

Reputation: 8945

Is .dup really creating a shallow copy?

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

Answers (1)

mu is too short
mu is too short

Reputation: 434665

You forget that == is actually a method from BasicObject:

obj == other → true or false
Equality — At the Object level, == returns true only if obj 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

Related Questions