Jesús Gabriel y Galán
1/9/2008 2:54:00 PM
On Jan 9, 2008 3:35 PM, Daniele Antani <daniele.cesarini@gmail.com> wrote:
> Hello to all,
>
> i can't understand the follow behaviour:
>
> class Player
> attr_accessor :hand
> def initialize(hand)
> @hand = hand
> end
> end
>
> def roba(player)
> p2 = Player.new(player.hand)
> change p2
> print "p2 = "
> p p2
> print "player = "
> p player
> end
>
> def change(player)
> player.hand.push(3)
> end
>
>
> p1 = Player.new([2, 3, 4])
> roba p1
>
> __END__
>
> output is:
> p2 = #<Player:0xb7c4919c @hand=[2, 3, 4, 3]>
> player = #<Player:0xb7c491c4 @hand=[2, 3, 4, 3]>
>
>
> Why the change affects both objects?
Because both players point to the same array object
in their @hand variables. To see what I mean try this:
irb(main):028:0> p = Player.new([2,3,4])
=> #<Player:0xb7c16044 @hand=[2, 3, 4]>
irb(main):029:0> p.hand.object_id
=> -606031798
irb(main):030:0> p2 = Player.new(p.hand)
=> #<Player:0xb7c00b40 @hand=[2, 3, 4]>
irb(main):031:0> p2.hand.object_id
=> -606031798
So when you push an element in the array,
both hands point to the same array and you see
the change in both player objects.
> I want to copy the first object and
> work on the copy without affecting the original.
You can dup the array in the initialize:
def initialize(hand)
@hand = hand.dup
end
Hope this helps,
Jesus.