[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Why this behaviour?

Daniele Antani

1/9/2008 2:36:00 PM

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? I want to copy the first object and
work on the copy without affecting the original.

Thanks
--
Posted via http://www.ruby-....

4 Answers

Jano Svitok

1/9/2008 2:49:00 PM

0

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)

This copies reference to the array, use #dup to create a copy (note
that it's not recursive):
- @hand = hand
+ @hand = hand.dup

> 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? I want to copy the first object and
> work on the copy without affecting the original.
>
> Thanks
> --
> Posted via http://www.ruby-....
>
>

Karl von Laudermann

1/9/2008 2:49:00 PM

0

On Jan 9, 9:35 am, Daniele Antani <daniele.cesar...@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
> Why the change affects both objects? I want to copy the first object and
> work on the copy without affecting the original.

Both Player objects contain a reference to the same array. What you
want is this:

class Player
attr_accessor :hand
def initialize(hand)
@hand = hand.clone
end
end

Sebastian Hungerecker

1/9/2008 2:52:00 PM

0

Daniele Antani wrote:
> I want to copy the first object and
> work on the copy without affecting the original.

Then do that. dup copies an object. Assignment does *not* copy.

HTH,
Sebastian
--
Jabber: sepp2k@jabber.org
ICQ: 205544826

Jesús Gabriel y Galán

1/9/2008 2:54:00 PM

0

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.