A little bit confused about array+array addition (bug or expected behavior?)

Discussion in 'Ruby' started by gga, Feb 16, 2005.

  1. gga

    gga Guest

    irb> a = [1,2]
    => [1, 2]
    irb> a
    => [1, 2, 3, 4]
    irb(main):082:0> a
    => [1, 2, 3, 4]

    So far so good...


    irb(main):082:0> def add(x)
    irb(main):084:1> x += [5,6]
    irb(main):085:1> end

    irb(main):087:0> add(a)
    => [1, 2, 3, 4, 5, 6]
    irb(main):088:0> a
    => [1, 2, 3, 4] ===>>> uh? am I not passing stuff by reference?
    where is 5, 6?


    irb(main):089:0> def add2(x)
    irb(main):089:0> x << [5,6]
    irb(main):089:0> end

    irb(main):090:0> add2(a)
    => [1, 2, 3, 4, [5, 6]]
    irb(main):091:0> a
    => [1, 2, 3, 4, [5, 6]] ==> seems logical, but then .... why +=
    behaves differently?

    > ruby -v

    ruby 1.8.2 (2004-12-25) [i686-linux]
    gga, Feb 16, 2005
    #1
    1. Advertising

  2. Re: A little bit confused about array+array addition (bug or expectedbehavior?)

    gga wrote:

    > irb(main):082:0> def add(x)
    > irb(main):084:1> x += [5,6]
    > irb(main):085:1> end
    >
    > irb(main):087:0> add(a)
    > => [1, 2, 3, 4, 5, 6]
    > irb(main):088:0> a
    > => [1, 2, 3, 4] ===>>> uh? am I not passing stuff by reference?
    > where is 5, 6?


    You are not passing variables by reference, you are passing objects by
    reference.

    Ruby does not have a built-in way of doing variable by reference as
    variables are usually not first-class objects. (They are names for objects.)

    You probably want to do x.replace(x + [5, 6]) or x.push(5, 6) which
    modify the object itself.

    This has come up frequently in the past -- if you are willing to do a
    bit of research on google groups you will find implementations of
    first-class variable objects, using lambdas for modifying variables in
    other scopes and more.
    Florian Gross, Feb 16, 2005
    #2
    1. Advertising

  3. gga

    Assaph Mehr Guest

    gga wrote:
    >
    > irb(main):082:0> def add(x)
    > irb(main):084:1> x += [5,6]
    > irb(main):085:1> end
    >
    > irb(main):087:0> add(a)
    > => [1, 2, 3, 4, 5, 6]
    > irb(main):088:0> a
    > => [1, 2, 3, 4] ===>>> uh? am I not passing stuff by

    reference?
    > where is 5, 6?


    In the method body you are reassing to the local variable x.
    .. x += [...]
    is translated to:
    .. x = x + [...]
    and #+ as we all know returns a copy of the object.

    You can see this with:

    .. def add(x)
    .. puts "Before #{x.object_id}"
    .. x += [5,6]
    .. puts "After #{x.object_id}"
    .. end

    So you ARE passing by ref, but then changing the ref to point to
    anotehr object.

    > irb(main):089:0> def add2(x)
    > irb(main):089:0> x << [5,6]
    > irb(main):089:0> end
    >
    > irb(main):090:0> add2(a)
    > => [1, 2, 3, 4, [5, 6]]
    > irb(main):091:0> a
    > => [1, 2, 3, 4, [5, 6]] ==> seems logical, but then .... why +=
    > behaves differently?


    The METHOD #<< modifies the object in place. The SYNTACTIC SUGAR += is
    changing a objeced referred to.

    HTH,
    Assaph
    Assaph Mehr, Feb 16, 2005
    #3
  4. gga

    gga Guest

    Yes, that's what I had figured. I had not realized the existance of
    the replace method. That's exactly what I was looking for.
    gga, Feb 17, 2005
    #4
  5. "Assaph Mehr" <> schrieb im Newsbeitrag
    news:...
    >
    > gga wrote:
    > >
    > > irb(main):082:0> def add(x)
    > > irb(main):084:1> x += [5,6]
    > > irb(main):085:1> end
    > >
    > > irb(main):087:0> add(a)
    > > => [1, 2, 3, 4, 5, 6]
    > > irb(main):088:0> a
    > > => [1, 2, 3, 4] ===>>> uh? am I not passing stuff by

    > reference?
    > > where is 5, 6?

    >
    > In the method body you are reassing to the local variable x.
    > . x += [...]
    > is translated to:
    > . x = x + [...]
    > and #+ as we all know returns a copy of the object.
    >
    > You can see this with:
    >
    > . def add(x)
    > . puts "Before #{x.object_id}"
    > . x += [5,6]
    > . puts "After #{x.object_id}"
    > . end
    >
    > So you ARE passing by ref, but then changing the ref to point to
    > anotehr object.
    >
    > > irb(main):089:0> def add2(x)
    > > irb(main):089:0> x << [5,6]
    > > irb(main):089:0> end
    > >
    > > irb(main):090:0> add2(a)
    > > => [1, 2, 3, 4, [5, 6]]
    > > irb(main):091:0> a
    > > => [1, 2, 3, 4, [5, 6]] ==> seems logical, but then .... why +=
    > > behaves differently?

    >
    > The METHOD #<< modifies the object in place. The SYNTACTIC SUGAR += is
    > changing a objeced referred to.


    Alternative is #concat

    >> a=[1,2]

    => [1, 2]
    >> def add3(a) a.concat [3,4] end

    => nil
    >> add3 a

    => [1, 2, 3, 4]
    >> a

    => [1, 2, 3, 4]


    Regards

    robert
    Robert Klemme, Feb 17, 2005
    #5
  6. In Message-Id: <>
    "gga" <> writes:

    > Yes, that's what I had figured. I had not realized the existance of
    > the replace method. That's exactly what I was looking for.


    But what you need in this particular case is Array#concat.

    irb(main):001:0> a=[1,2,3]
    => [1, 2, 3]
    irb(main):002:0> a.concat([4,5])
    => [1, 2, 3, 4, 5]
    irb(main):003:0> a
    => [1, 2, 3, 4, 5]


    --
    February 17, 2005
    Time and tide wait for no man.
    YANAGAWA Kazuhisa, Feb 17, 2005
    #6
  7. gga

    Stefan Lang Guest

    gga wrote:

    > irb(main):082:0> def add(x)
    > irb(main):084:1>    x += [5,6]


    This creates a new array and assigns it to the local variable x.
    The original array passed into this method won't be modified.
    But the result of the statement is the new array, which will
    be returned.

    > irb(main):085:1> end
    >
    > irb(main):087:0> add(a)
    > => [1, 2, 3, 4, 5, 6]
    > irb(main):088:0> a
    > => [1, 2, 3, 4]        ===>>> uh?  am I not passing stuff by reference?
    > where is 5, 6?
    >
    >
    > irb(main):089:0> def add2(x)
    > irb(main):089:0>   x << [5,6]


    << appends to the existing array

    > irb(main):089:0> end
    Stefan Lang, Feb 17, 2005
    #7
    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. Ed Young
    Replies:
    4
    Views:
    322
    Ed Young
    Aug 10, 2003
  2. Generic Usenet Account
    Replies:
    13
    Views:
    559
    Rick N. Backer
    Jul 12, 2005
  3. shapper
    Replies:
    1
    Views:
    309
    =?Utf-8?B?Q2hldGFuIENoYXBoZWthcg==?=
    Mar 8, 2007
  4. shapper
    Replies:
    0
    Views:
    277
    shapper
    Mar 11, 2007
  5. Hendrik Maryns

    Confused: Java6 32-bit vs. 64-bit

    Hendrik Maryns, May 2, 2007, in forum: Java
    Replies:
    3
    Views:
    571
    Tom Hawtin
    May 2, 2007
Loading...

Share This Page