Array +=

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 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

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

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

···

2007/10/12, mortee <mortee.lists@kavemalna.hu>:

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 <shortcutter@googlemail.com> wrote:

2007/10/12, mortee <mortee.lists@kavemalna.hu>:
> 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

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 <shortcutter@googlemail.com> wrote:

2007/10/12, mortee <mortee.lists@kavemalna.hu>:
> 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.co.uk

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

Cheers

robert

···

2007/10/12, Simon Mullis <simon@mullis.co.uk>:

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.

Yep... concat it is!

Cheers!

SM

···

On 10/12/07, Robert Klemme <shortcutter@googlemail.com> wrote:

2007/10/12, Simon Mullis <simon@mullis.co.uk>:
> 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!
:wink:

Cheers

robert

--
Simon Mullis
_________________
simon@mullis.co.uk