# Ridiculous behavoir of Array#push and Array#clear

**URL:** <https://www.ruby-forum.com/t/ridiculous-behavoir-of-array-push-and-array-clear/78277>\
**Category:** Ruby\
**Created:** [March 8, 2006, 9:45am UTC](https://www.ruby-forum.com/t/ridiculous-behavoir-of-array-push-and-array-clear/78277 "2006-03-08T09:45:27Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 8, 2006, 9:45am UTC](https://www.ruby-forum.com/t/ridiculous-behavoir-of-array-push-and-array-clear/78277/1 "2006-03-08T09:45:27Z")

</div>

See bellow code please.

```
  1 obj1 = "object1"
  2 obj2 = "object2"
  3 obj3 = "object3"
  4
  5 arr1 = Array.new
  6 arr2 = Array.new
  7
  8 arr1 << obj1
  9 arr1 << obj2
 10
 11 arr2 << obj3
 12
 13 puts "<arr1>"
 14 arr1.each {
 15 | element |
 16 puts element
 17 }
 18
 19 puts "<arr2>"
 20 arr2.each {
 21 | element |
 22 puts element
 23 }
 24
 25 arr1.push( arr2 )
 26 puts "<arr1 << arr2>"
 27 arr1.each {
 28 | element |
 29 puts element
 30 }
 31
 32 arr2.clear
 33 puts "<arr2.clear>"
 34
 35 puts "<arr2>"
 36 arr2.each {
 37 | element |
 38 puts element
 39 }
 40
 41 puts "<arr1>"
 42 arr1.each {
 43 | element |
 44 puts element
 45 }

```

result is…

object1 object2 object3 \<arr1 \< object1 object2 object3 object1 object2

In the last list of arr1, there’s no object3. Why? Does Array#push()  
method append the array as a refrence? If so, why it does? And after  
arr2 had been cleared, I still can access to 3rd member of arr1 without  
exceptions or errors.

Yes, I can use clone() method for Array#push. But before, I hope to  
know the reason why RUBY’s Array#push method works like above.

Thanks.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 8, 2006, 10:25am UTC](https://www.ruby-forum.com/t/ridiculous-behavoir-of-array-push-and-array-clear/78277/2 "2006-03-08T10:25:32Z")

</div>

inspect will give you the answer:

On 3/8/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> 11 arr2 << obj3
> 12
> 13 puts "<arr1>"
> 
> ```

```
    14 puts arr1.inspect

```

→ [“object1”, “object2”]

> ```
> 19 puts "<arr2>"
> 
> ```

```
    20 puts arr2.inspect

```

→ [“object3”]

> ```
> 25 arr1.push( arr2 )
> 26 puts "<arr1 << arr2>"
> 
> ```

```
    27 puts arr1.inspect

```

→ [“object1”, “object2”, [ "object3\*] ]  
# notice that the third Element of arr1 is not obj3, but arr2!

> ```
> 32 arr2.clear
> 
> ```

```
    # fine, emptying arr2...

```

> ```
> 33 puts "<arr2.clear>"
> 34
> 35 puts "<arr2>"
> 
> ```

```
    36 puts arr2.inspect

```

→ []

> ```
> 41 puts "<arr1>"
> 
> ```

```
    42 puts arr1.inspect

```

→ [“object1”, “object2”, [] ]  
# the third Element of arr1 is still arr2, it just has been  
cleared,  
# so not a trace of obj3…

> Yes, I can use clone() method for Array#push. But before, I hope to  
> know the reason why RUBY’s Array#push method works like above.  
> …or you could do:  
> 25 arr1.concat( arr2 )  
> → [“object1”, “object2”, “object3”]

for any questions like that: try irb - I can only recommend it…

hth

Hannes

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 8, 2006, 10:28am UTC](https://www.ruby-forum.com/t/ridiculous-behavoir-of-array-push-and-array-clear/78277/3 "2006-03-08T10:28:33Z")

</div>

> In the last list of arr1, there’s no object3. Why? Does Array#push()  
> method append the array as a refrence?

Yes, array elements are just references to objects pretty much in the  
same  
way a variable points to an object. In your case, when you push arr2  
into  
arr1, what you’re doing is making the 3rd element of the array be a  
reference to the object pointed to by the variable arr2:

irb(main):006:0\> arr1 =[]  
=\> []  
irb(main):007:0\> arr2 =[]  
=\> []  
irb(main):008:0\> arr1 \<\< “object1”  
=\> [“object1”]  
irb(main):009:0\> arr1 \<\< “object2”  
=\> [“object1”, “object2”]  
irb(main):010:0\> arr2 \<\< “object3”  
=\> [“object3”]  
irb(main):011:0\> arr1.push(arr2)  
=\> [“object1”, “object2”, [“object3”]]

irb(main):015:0\> arr2.object\_id # \<==== arr2 and arr1[2] point to  
the  
same object  
=\> 22439224  
irb(main):018:0\> arr1[2].object\_id  
=\> 22439224

> If so, why it does? And after  
> arr2 had been cleared, I still can access to 3rd member of arr1 without  
> exceptions or errors.

The call to arr2.clear() clears the contents of the array object  
referenced  
by arr2, which happens to be the same array the 3rd element of arr1  
points  
to:

irb(main):012:0\> arr2.clear  
=\> []  
irb(main):013:0\> arr1  
=\> [“object1”, “object2”, []]

The 3rd element is still in arr1, but now it just points to an empty  
array.

Hope this helps,

Martin

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 8, 2006, 11:54am UTC](https://www.ruby-forum.com/t/ridiculous-behavoir-of-array-push-and-array-clear/78277/4 "2006-03-08T11:54:12Z")

</div>

This is because arr1 is storing a _reference_ to arr2. If you want to  
avoid this behaviour you could use any of the following:

arr1 += arr2 (generates new array, old arr1 is now garbage)  
arr1 \<\< arr2.dup (copies arr2, the copy is stored as an element of  
arr1)  
(arr1 \<\< arr2).flatten! (ideal, but most verbose)

The first two generate new objects. I believe the third doesn’t (I may  
be wrong). Take your pick.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 8, 2006, 10:37am UTC](https://www.ruby-forum.com/t/ridiculous-behavoir-of-array-push-and-array-clear/78277/5 "2006-03-08T10:37:38Z")

</div>

Changing your code to output the actual arrays:

> arr2 \<\< obj3
> 
> arr2.clear  
> puts “\<arr2.clear\>”
> 
> puts “”  
> p arr2
> 
> puts “”  
> p arr1

gives you:

> [“object1”, “object2”, []]  
> which should give you a hint as to what’s going on.

Pete Y.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 8, 2006, 4:32pm UTC](https://www.ruby-forum.com/t/ridiculous-behavoir-of-array-push-and-array-clear/78277/6 "2006-03-08T16:32:24Z")

</div>

In Message-Id: [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
“Timothy G.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> (arr1 \<\< arr2).flatten! (ideal, but most verbose)
> 
> The first two generate new objects. I believe the third doesn’t (I may  
> be wrong). Take your pick.

Or use Array#concat to concatenate two arrays destructively.

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

```
