# Array +=

**URL:** <https://rubytalk.org/t/array/41337>\
**Category:** ruby-talk\
**Created:** [12 October 2007 10:54 UTC](https://rubytalk.org/t/array/41337 "2007-10-12T10:54:13Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Simon\_Mullis1](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Simon\_Mullis1](https://rubytalk.org/u/Simon_Mullis1)\
**Post date:** [12 October 2007 10:54 UTC](https://rubytalk.org/t/array/41337/1 "2007-10-12T10:54:13Z")

</div>

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]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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

---

<div class="post-metadata">

**Author:** ![mortee](https://avatars.discourse-cdn.com/v4/letter/m/50afbb/32.png) [@mortee](https://rubytalk.org/u/mortee)\
**Post date:** [12 October 2007 11:35 UTC](https://rubytalk.org/t/array/41337/2 "2007-10-12T11:35:02Z")

</div>

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]  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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

---

<div class="post-metadata">

**Author:** ![Florian\_Frank2](https://avatars.discourse-cdn.com/v4/letter/f/a587f6/32.png) [@Florian\_Frank2](https://rubytalk.org/u/Florian_Frank2)\
**Post date:** [12 October 2007 11:53 UTC](https://rubytalk.org/t/array/41337/3 "2007-10-12T11:53:11Z")

</div>

Simon Mullis wrote:

> Is there alternate syntax I should use?  
> &nbsp;&nbsp;  
> Did you you mean this?

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

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

> **···**
>
> --  
> Florian Frank

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [12 October 2007 11:56 UTC](https://rubytalk.org/t/array/41337/4 "2007-10-12T11:56:13Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Simon\_Mullis1](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Simon\_Mullis1](https://rubytalk.org/u/Simon_Mullis1)\
**Post date:** [12 October 2007 13:22 UTC](https://rubytalk.org/t/array/41337/5 "2007-10-12T13:22:36Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Simon\_Mullis1](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Simon\_Mullis1](https://rubytalk.org/u/Simon_Mullis1)\
**Post date:** [12 October 2007 13:24 UTC](https://rubytalk.org/t/array/41337/6 "2007-10-12T13:24:54Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [12 October 2007 13:51 UTC](https://rubytalk.org/t/array/41337/7 "2007-10-12T13:51:41Z")

</div>

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

> **···**
>
> 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.

---

<div class="post-metadata">

**Author:** ![Simon\_Mullis1](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Simon\_Mullis1](https://rubytalk.org/u/Simon_Mullis1)\
**Post date:** [12 October 2007 19:34 UTC](https://rubytalk.org/t/array/41337/8 "2007-10-12T19:34:07Z")

</div>

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!  
> > 😉
> > 
> > Cheers
> > 
> > robert
> 
> --  
> Simon Mullis  
> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> simon@mullis.co.uk
