Why this behaviour?

Discussion in 'Ruby' started by Daniele Antani, Jan 9, 2008.

  1. 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-forum.com/.
     
    Daniele Antani, Jan 9, 2008
    #1
    1. Advertising

  2. Daniele Antani

    Jano Svitok Guest

    On Jan 9, 2008 3:35 PM, Daniele Antani <> 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-forum.com/.
    >
    >
     
    Jano Svitok, Jan 9, 2008
    #2
    1. Advertising

  3. On Jan 9, 9:35 am, Daniele Antani <> 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
     
    Karl von Laudermann, Jan 9, 2008
    #3
  4. 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:
    ICQ: 205544826
     
    Sebastian Hungerecker, Jan 9, 2008
    #4
  5. On Jan 9, 2008 3:35 PM, Daniele Antani <> 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.
     
    Jesús Gabriel y Galán, Jan 9, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?VGltOjouLg==?=

    Why, why, why???

    =?Utf-8?B?VGltOjouLg==?=, Jan 27, 2005, in forum: ASP .Net
    Replies:
    6
    Views:
    579
    Juan T. Llibre
    Jan 27, 2005
  2. Horace Nunley

    why why why does function not work

    Horace Nunley, Sep 27, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    470
    =?Utf-8?B?UGV0ZXIgQnJvbWJlcmcgW0MjIE1WUF0=?=
    Sep 27, 2006
  3. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    921
    Mark Rae
    Dec 21, 2006
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,072
    Smokey Grindel
    Dec 2, 2006
  5. Andy Chambers
    Replies:
    1
    Views:
    395
    Daniel Dyer
    May 14, 2007
Loading...

Share This Page