# Array +=

**URL:** <https://www.ruby-forum.com/t/array/117049>\
**Category:** Ruby\
**Created:** [October 12, 2007, 12:55pm UTC](https://www.ruby-forum.com/t/array/117049 "2007-10-12T12:55:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![sijomo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/87869e/32.png) [@sijomo](https://www.ruby-forum.com/u/sijomo)\
**Post date:** [October 12, 2007, 12:55pm UTC](https://www.ruby-forum.com/t/array/117049/1 "2007-10-12T12:55:11Z")

</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]  
> > ^  
> > 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:** ![sijomo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/87869e/32.png) [@sijomo](https://www.ruby-forum.com/u/sijomo)\
**Post date:** [October 12, 2007, 2:16pm UTC](https://www.ruby-forum.com/t/array/117049/2 "2007-10-12T14:16:31Z")

</div>

Simon M. wrote:

> ```
> 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:** ![sijomo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/87869e/32.png) [@sijomo](https://www.ruby-forum.com/u/sijomo)\
**Post date:** [October 12, 2007, 2:28pm UTC](https://www.ruby-forum.com/t/array/117049/3 "2007-10-12T14:28:48Z")

</div>

2007/10/12, mortee [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > ```
> > ^
> > 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:** ![sijomo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/87869e/32.png) [@sijomo](https://www.ruby-forum.com/u/sijomo)\
**Post date:** [October 12, 2007, 3:23pm UTC](https://www.ruby-forum.com/t/array/117049/4 "2007-10-12T15:23:22Z")

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

---

<div class="post-metadata">

**Author:** ![sijomo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/87869e/32.png) [@sijomo](https://www.ruby-forum.com/u/sijomo)\
**Post date:** [October 12, 2007, 2:35pm UTC](https://www.ruby-forum.com/t/array/117049/5 "2007-10-12T14:35:16Z")

</div>

Simon M. 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.

---

<div class="post-metadata">

**Author:** ![sijomo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/87869e/32.png) [@sijomo](https://www.ruby-forum.com/u/sijomo)\
**Post date:** [October 12, 2007, 3:26pm UTC](https://www.ruby-forum.com/t/array/117049/6 "2007-10-12T15:26:53Z")

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

---

<div class="post-metadata">

**Author:** ![sijomo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/87869e/32.png) [@sijomo](https://www.ruby-forum.com/u/sijomo)\
**Post date:** [October 12, 2007, 4:34pm UTC](https://www.ruby-forum.com/t/array/117049/7 "2007-10-12T16:34:55Z")

</div>

2007/10/12, Simon M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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

---

<div class="post-metadata">

**Author:** ![sijomo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/87869e/32.png) [@sijomo](https://www.ruby-forum.com/u/sijomo)\
**Post date:** [October 12, 2007, 9:34pm UTC](https://www.ruby-forum.com/t/array/117049/8 "2007-10-12T21:34:55Z")

</div>

Yep… concat it is!

Cheers!

SM
