Nested Arrays in Method Definitions--a puzzle

Discussion in 'Ruby' started by Jonah Bloch-Johnson, Aug 20, 2008.

  1. Hello there Ruby-minded people!

    I am writing because I am somewhat stumped by why the following
    discrepency occurs; having defined the following:

    class Warfare
    def haves
    x = [1]
    y = []
    y << x
    x = [2] # (compare this)
    y
    end
    def havenots
    x = [1]
    y = []
    y << x
    x[0] = 2 # (to this)
    y
    end
    end

    I get this in irb:

    >> load 'snah.rb'

    => true
    >> a = Warfare.new

    => #<Warfare:0x33a93c>
    >> a.haves

    => [[1]]
    >> a.havenots

    => [[2]]

    Why does meddling with the innards of the "x" have retroactive
    repercussions, whereas redefining it outright does not?

    Any insight would be greatly appreciated.

    -Jonah
    Jonah Bloch-Johnson, Aug 20, 2008
    #1
    1. Advertising

  2. On Tue, Aug 19, 2008 at 4:16 PM, Jonah Bloch-Johnson
    <> wrote:
    >
    > def haves
    > x = [1]
    > y = []
    > y << x
    > x = [2] # (compare this)
    > y
    > end
    >
    > Why does meddling with the innards of the "x" have retroactive
    > repercussions, whereas redefining it outright does not?


    When you say 'x = [2]' you aren't redefining the object x, you are
    taking the variable 'x' and binding it to a new object. When you say y
    << x, you are inserting the object that x was pointing to at that
    moment into y, not the variable x. Think of a variable as an alias for
    an object - what is actually passed around are the objects themselves,
    but you can refer to them by any of their current aliases.

    martin
    Martin DeMello, Aug 20, 2008
    #2
    1. Advertising

  3. Jonah Bloch-Johnson

    Adam Shelly Guest

    On 8/19/08, Jonah Bloch-Johnson <> wrote:

    > I am writing because I am somewhat stumped by why the following discrepency occurs...


    Variables and Array entries hold references to objects.

    irb(main):001:0> x=[1]
    => [1]
    irb(main):002:0> x.object_id
    => 20774910

    irb(main):003:0> y=[];y<<x
    => [[1]]
    irb(main):004:0> y[0].object_id
    => 20774910 #the same object that x referrs to

    irb(main):005:0> x=[2]
    => [2]
    irb(main):006:0> x.object_id
    => 21222360 #now x refers to the newly created array

    irb(main):008:0> y
    => [[1]]
    irb(main):007:0> y[0].object_id
    => 20774910 #but y still holds a reference to the old one.

    irb(main):009:0> y=[x]
    => [[2]]
    irb(main):010:0> y[0].object_id
    => 21222360 #y[0] is now a reference to the same Array as x

    irb(main):011:0> x[0]=4
    => 4
    irb(main):013:0> y
    => [[4]] #so changes to the content of that Array are visible
    through y's reference.


    hope this helps,
    -Adam



























































    > x = [1]


    [1] is an Array object, x is a variable referring to that array
    > y = []

    y referrs to a 2nd Array
    > y << x


    And now that array contains a reference to

    > x = [2] # (compare this)


    Here you are creating an array, labeling it 'x', and storing a
    reference to it in the array labeled y. Then you reassign the 'x'
    label to yet another array (the one containing 2).

    > end
    > def havenots
    > x = [1]
    > y = []
    > y << x
    > x[0] = 2 # (to this)
    > y
    > end
    > end
    >
    > I get this in irb:
    >
    > >
    > > > load 'snah.rb'
    > > >

    > >

    > => true
    > >
    > > > a = Warfare.new
    > > >

    > >

    > => #<Warfare:0x33a93c>
    > >
    > > > a.haves
    > > >

    > >

    > => [[1]]
    > >
    > > > a.havenots
    > > >

    > >

    > => [[2]]
    >
    > Why does meddling with the innards of the "x" have retroactive
    > repercussions, whereas redefining it outright does not?
    >
    > Any insight would be greatly appreciated.
    >
    > -Jonah
    >
    >
    >
    Adam Shelly, Aug 20, 2008
    #3
  4. Many many many thanks, Adam and Martin! I do think this clears it up.

    Quoting Adam Shelly <>:

    > On 8/19/08, Jonah Bloch-Johnson <> wrote:
    >
    >> I am writing because I am somewhat stumped by why the following =20
    >> discrepency occurs...

    >
    > Variables and Array entries hold references to objects.
    >
    > irb(main):001:0> x=3D[1]
    > =3D> [1]
    > irb(main):002:0> x.object_id
    > =3D> 20774910
    >
    > irb(main):003:0> y=3D[];y<<x
    > =3D> [[1]]
    > irb(main):004:0> y[0].object_id
    > =3D> 20774910 #the same object that x referrs to
    >
    > irb(main):005:0> x=3D[2]
    > =3D> [2]
    > irb(main):006:0> x.object_id
    > =3D> 21222360 #now x refers to the newly created array
    >
    > irb(main):008:0> y
    > =3D> [[1]]
    > irb(main):007:0> y[0].object_id
    > =3D> 20774910 #but y still holds a reference to the old one.
    >
    > irb(main):009:0> y=3D[x]
    > =3D> [[2]]
    > irb(main):010:0> y[0].object_id
    > =3D> 21222360 #y[0] is now a reference to the same Array as x
    >
    > irb(main):011:0> x[0]=3D4
    > =3D> 4
    > irb(main):013:0> y
    > =3D> [[4]] #so changes to the content of that Array are visible
    > through y's reference.
    >
    >
    > hope this helps,
    > -Adam
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >> x =3D [1]

    >
    > [1] is an Array object, x is a variable referring to that array
    >> y =3D []

    > y referrs to a 2nd Array
    >> y << x

    >
    > And now that array contains a reference to
    >
    >> x =3D [2] # (compare this)

    >
    > Here you are creating an array, labeling it 'x', and storing a
    > reference to it in the array labeled y. Then you reassign the 'x'
    > label to yet another array (the one containing 2).
    >
    >> end
    >> def havenots
    >> x =3D [1]
    >> y =3D []
    >> y << x
    >> x[0] =3D 2 # (to this)
    >> y
    >> end
    >> end
    >>
    >> I get this in irb:
    >>
    >> >
    >> > > load 'snah.rb'
    >> > >
    >> >

    >> =3D> true
    >> >
    >> > > a =3D Warfare.new
    >> > >
    >> >

    >> =3D> #<Warfare:0x33a93c>
    >> >
    >> > > a.haves
    >> > >
    >> >

    >> =3D> [[1]]
    >> >
    >> > > a.havenots
    >> > >
    >> >

    >> =3D> [[2]]
    >>
    >> Why does meddling with the innards of the "x" have retroactive
    >> repercussions, whereas redefining it outright does not?
    >>
    >> Any insight would be greatly appreciated.
    >>
    >> -Jonah
    >>
    >>
    >>

    >
    >
    Jonah Bloch-Johnson, Aug 20, 2008
    #4
    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. Tony Johansson

    Nested class definitions

    Tony Johansson, May 19, 2005, in forum: C++
    Replies:
    1
    Views:
    425
    Victor Bazarov
    May 19, 2005
  2. Paddy

    Nested Parameter Definitions

    Paddy, Feb 25, 2007, in forum: Python
    Replies:
    10
    Views:
    462
    Paddy
    Feb 26, 2007
  3. Replies:
    4
    Views:
    453
  4. erichain

    Puzzle about multi definitions

    erichain, Mar 21, 2007, in forum: C Programming
    Replies:
    2
    Views:
    230
    Jack Klein
    Mar 22, 2007
  5. Philipp
    Replies:
    21
    Views:
    1,109
    Philipp
    Jan 20, 2009
Loading...

Share This Page