Array +=

Discussion in 'Ruby' started by Simon Mullis, Oct 12, 2007.

  1. Simon Mullis

    Simon Mullis Guest

    Hi All,

    Question re Array method += and

    >> a = []

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

    => [1, 2, 3, 4]

    And

    >> (a ||= []) << [1, 2, 3, 4]

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

    But

    >> ( a ||= [] ) += [ 1, 2, 3, 4 ]

    SyntaxError: compile error
    (irb):28: syntax error, unexpected tOP_ASGN, expecting $end
    ( a ||= [] ) += [ 1, 2, 3, 4 ]
    ^
    from (irb):28

    Why?

    I guess it's a precedence issue. '<<' is a method in the Array class.
    '+=' is not.

    Is there alternate syntax I should use?

    Thanks

    SM
    Simon Mullis, Oct 12, 2007
    #1
    1. Advertising

  2. Simon Mullis

    mortee Guest

    Simon Mullis wrote:
    >>> (a ||= []) << [1, 2, 3, 4]

    > => [[1, 2, 3, 4]]
    >
    > But
    >
    >>> ( a ||= [] ) += [ 1, 2, 3, 4 ]

    > SyntaxError: compile error
    > (irb):28: syntax error, unexpected tOP_ASGN, expecting $end
    > ( a ||= [] ) += [ 1, 2, 3, 4 ]
    > ^
    > from (irb):28
    >
    > Why?
    >
    > I guess it's a precedence issue. '<<' is a method in the Array class.
    > '+=' is not.


    The difference is that << is a method, += is an assignment. (a ||= [])
    returns an object, on which you can call a method, but you can't assign
    to. You can only assign to the a variable itself, which (a ||= []) is
    not. I guess.

    mortee
    mortee, Oct 12, 2007
    #2
    1. Advertising

  3. Simon Mullis wrote:
    > Is there alternate syntax I should use?
    >


    Did you you mean this?

    (a ||= []).concat [ 1, 2, 3, 4 ]

    concat modifies a, like << would. It's usually faster to concatenate
    than to add and reassign.

    --
    Florian Frank
    Florian Frank, Oct 12, 2007
    #3
  4. 2007/10/12, mortee <>:
    > Simon Mullis wrote:
    > >>> (a ||= []) << [1, 2, 3, 4]

    > > => [[1, 2, 3, 4]]
    > >
    > > But
    > >
    > >>> ( a ||= [] ) += [ 1, 2, 3, 4 ]

    > > SyntaxError: compile error
    > > (irb):28: syntax error, unexpected tOP_ASGN, expecting $end
    > > ( a ||= [] ) += [ 1, 2, 3, 4 ]
    > > ^
    > > from (irb):28
    > >
    > > Why?
    > >
    > > I guess it's a precedence issue. '<<' is a method in the Array class.
    > > '+=' is not.


    No, it's not a precedence issue. Btw, you are comparing apples and
    oranges here: += and << are not equivalent (see also further below):

    irb(main):001:0> a=%w{foo bar}
    => ["foo", "bar"]
    irb(main):002:0> b=a.dup
    => ["foo", "bar"]
    irb(main):003:0> c=a.dup
    => ["foo", "bar"]
    irb(main):004:0> b << a
    => ["foo", "bar", ["foo", "bar"]]
    irb(main):005:0> c += a
    => ["foo", "bar", "foo", "bar"]

    << adds the whole Array as one object while += "appends" the Array.
    You rather want Array#concat.

    > The difference is that << is a method, += is an assignment. (a ||= [])
    > returns an object, on which you can call a method, but you can't assign
    > to. You can only assign to the a variable itself, which (a ||= []) is
    > not. I guess.


    Exactly: the expression (a||=[]) is not an lvalue, i.e. cannot
    assigned to. But you can do

    ( a ||= [] ).concat [ 1, 2, 3, 4 ]

    Simon, please also keep in mind that += and << have different
    semantics. += will create a new Array while << appends to the current
    one.

    Kind regards

    robert
    Robert Klemme, Oct 12, 2007
    #4
  5. Simon Mullis

    Simon Mullis Guest

    I love this list... I send a mail, go off to a meeting, come back and
    I have explanation, discussion and solution!

    Thanks to all who responded.

    Cheers

    SM

    On 10/12/07, Robert Klemme <> wrote:
    > 2007/10/12, mortee <>:
    > > Simon Mullis wrote:
    > > >>> (a ||= []) << [1, 2, 3, 4]
    > > > => [[1, 2, 3, 4]]
    > > >
    > > > But
    > > >
    > > >>> ( a ||= [] ) += [ 1, 2, 3, 4 ]
    > > > SyntaxError: compile error
    > > > (irb):28: syntax error, unexpected tOP_ASGN, expecting $end
    > > > ( a ||= [] ) += [ 1, 2, 3, 4 ]
    > > > ^
    > > > from (irb):28
    > > >
    > > > Why?
    > > >
    > > > I guess it's a precedence issue. '<<' is a method in the Array class.
    > > > '+=' is not.

    >
    > No, it's not a precedence issue. Btw, you are comparing apples and
    > oranges here: += and << are not equivalent (see also further below):
    >
    > irb(main):001:0> a=%w{foo bar}
    > => ["foo", "bar"]
    > irb(main):002:0> b=a.dup
    > => ["foo", "bar"]
    > irb(main):003:0> c=a.dup
    > => ["foo", "bar"]
    > irb(main):004:0> b << a
    > => ["foo", "bar", ["foo", "bar"]]
    > irb(main):005:0> c += a
    > => ["foo", "bar", "foo", "bar"]
    >
    > << adds the whole Array as one object while += "appends" the Array.
    > You rather want Array#concat.
    >
    > > The difference is that << is a method, += is an assignment. (a ||= [])
    > > returns an object, on which you can call a method, but you can't assign
    > > to. You can only assign to the a variable itself, which (a ||= []) is
    > > not. I guess.

    >
    > Exactly: the expression (a||=[]) is not an lvalue, i.e. cannot
    > assigned to. But you can do
    >
    > ( a ||= [] ).concat [ 1, 2, 3, 4 ]
    >
    > Simon, please also keep in mind that += and << have different
    > semantics. += will create a new Array while << appends to the current
    > one.
    >
    > Kind regards
    >
    > robert
    >
    >
    Simon Mullis, Oct 12, 2007
    #5
  6. Simon Mullis

    Simon Mullis Guest

    Thanks for this Robert.

    The difference between the two is exactly why I wanted to use += and
    not <<. I want to add many arrays to one big one and not have to use
    the extra step of Array#flatten at the end.

    SM



    On 10/12/07, Robert Klemme <> wrote:
    > 2007/10/12, mortee <>:
    > > Simon Mullis wrote:
    > > >>> (a ||= []) << [1, 2, 3, 4]
    > > > => [[1, 2, 3, 4]]
    > > >
    > > > But
    > > >
    > > >>> ( a ||= [] ) += [ 1, 2, 3, 4 ]
    > > > SyntaxError: compile error
    > > > (irb):28: syntax error, unexpected tOP_ASGN, expecting $end
    > > > ( a ||= [] ) += [ 1, 2, 3, 4 ]
    > > > ^
    > > > from (irb):28
    > > >
    > > > Why?
    > > >
    > > > I guess it's a precedence issue. '<<' is a method in the Array class.
    > > > '+=' is not.

    >
    > No, it's not a precedence issue. Btw, you are comparing apples and
    > oranges here: += and << are not equivalent (see also further below):
    >
    > irb(main):001:0> a=%w{foo bar}
    > => ["foo", "bar"]
    > irb(main):002:0> b=a.dup
    > => ["foo", "bar"]
    > irb(main):003:0> c=a.dup
    > => ["foo", "bar"]
    > irb(main):004:0> b << a
    > => ["foo", "bar", ["foo", "bar"]]
    > irb(main):005:0> c += a
    > => ["foo", "bar", "foo", "bar"]
    >
    > << adds the whole Array as one object while += "appends" the Array.
    > You rather want Array#concat.
    >
    > > The difference is that << is a method, += is an assignment. (a ||= [])
    > > returns an object, on which you can call a method, but you can't assign
    > > to. You can only assign to the a variable itself, which (a ||= []) is
    > > not. I guess.

    >
    > Exactly: the expression (a||=[]) is not an lvalue, i.e. cannot
    > assigned to. But you can do
    >
    > ( a ||= [] ).concat [ 1, 2, 3, 4 ]
    >
    > Simon, please also keep in mind that += and << have different
    > semantics. += will create a new Array while << appends to the current
    > one.
    >
    > Kind regards
    >
    > robert
    >
    >



    --
    Simon Mullis
    _________________
    Simon Mullis, Oct 12, 2007
    #6
  7. 2007/10/12, Simon Mullis <>:
    > Thanks for this Robert.
    >
    > The difference between the two is exactly why I wanted to use += and
    > not <<. I want to add many arrays to one big one and not have to use
    > the extra step of Array#flatten at the end.


    That's why you should be using #concat (more efficient) unless you do
    not want to modify the original array. Read the solutions properly!
    ;-)

    Cheers

    robert
    Robert Klemme, Oct 12, 2007
    #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. Daniel
    Replies:
    1
    Views:
    1,034
    Kevin Collins
    Aug 14, 2003
  2. S300
    Replies:
    4
    Views:
    21,965
    Roedy Green
    Aug 19, 2003
  3. Mara Guida

    const and array of array (of array ...)

    Mara Guida, Sep 2, 2009, in forum: C Programming
    Replies:
    3
    Views:
    473
    David RF
    Sep 3, 2009
  4. Tom
    Replies:
    3
    Views:
    197
    salsablr
    Dec 20, 2004
  5. Tuan  Bui
    Replies:
    14
    Views:
    462
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page