0

I came across this problem and I need some help understanding why the original object was also changed; I was under the impression that ".dup" will create a new object for the pointer to reference, is this wrong?

class Pawn
  attr_accessor :position

  def initialize(position)
    @position = position
  end
end

pawn = Pawn.new([0, 1])
pawn_copy = pawn.dup

pawn_copy.position[1] = "CHANGED"
pawn.position #=> the result is [0, "CHANGED"]
Selcuk
  • 57,004
  • 12
  • 102
  • 110
  • What language is the upper part? – Klaus D. Nov 21 '19 at 02:58
  • 1
    This is Ruby, not Python. `dup` creates a shallow copy, it won't duplicate the inner objects (such as `position`). In this case `pawn_copy = Pawn.new(pawn.position.dup)` may work (not tested). – Selcuk Nov 21 '19 at 03:03
  • 1
    @Karen : For creating a deep copy, do a `Marshal.load(Marshal.dump(pawn))` instead of `pawn.dup`. – user1934428 Nov 21 '19 at 08:33
  • 1
    Short answer: Because you didn't modify `pawn_copy` at all. You modified the array stored under the *position* attribute. Both `pawn` and `pawn_copy` hold a reference to this same array. – 3limin4t0r Nov 21 '19 at 11:06
  • Add a `initialize_copy` method to your class (`def initialize_copy(orig); @position = @position.dup; end`. The `pawn.dup` works. – steenslag Nov 21 '19 at 15:14

0 Answers0