So what is happening can be seen by inspecting object ids. In the first instance we create two new arrays which are referenced by variables array1 and array2 respectively.
1.9.2p290 :001 > array1 = ["a", "b", "c", "d", "e"]
=> ["a", "b", "c", "d", "e"]
1.9.2p290 :002 > array1.object_id
=> 4320500
1.9.2p290 :003 > array2 = Array.new
=>
1.9.2p290 :004 > array2.object_id
=> 4205400
We then add the array which is referenced by array1 as the first element of array2
1.9.2p290 :005 > array2 << array1
=> [["a", "b", "c", "d", "e"]]
1.9.2p290 :006 > array2.first.object_id == array1.object_id
=> true
So in fact array2 now contains a reference to array1. This then does what we expect when the array referenced by array1 is cleared. You will notice the object reference remains the same.
1.9.2p290 :007 > array1.clear
=>
1.9.2p290 :008 > array2
=> []
1.9.2p290 :009 > array2.first.object_id == array1.object_id
=> true
Now what happens if we do the same thing, except instead of clearing the array referenced by array1, we assign a new array to array1.
1.9.2p290 :010 > array1 = ["a", "b", "c", "d", "e"]
=> ["a", "b", "c", "d", "e"]
1.9.2p290 :011 > array1.object_id
=> 5232600
1.9.2p290 :012 > array2 = Array.new
=>
1.9.2p290 :013 > array2.object_id
=> 5189800
1.9.2p290 :014 > array2 << array1
=> [["a", "b", "c", "d", "e"]]
1.9.2p290 :015 > array2.first.object_id == array1.object_id
=> true
1.9.2p290 :016 > array1 = Array.new
=>
1.9.2p290 :017 > array2.first.object_id == array1.object_id
=> false
1.9.2p290 :018 > array2
=> [["a", "b", "c", "d", "e"]]
As you can see here, when array1 is told to reference a new array, the array it used to reference is still intact and remains in existence due to array2 still holding a reference to it. The variable array1 now points to a shiny new array and thus methods called via array1 are no longer received by the one we shoved into array2.
1.9.2p290 :019 > array1.object_id
=> 5144400
1.9.2p290 :020 > array2.object_id
=> 5189800
1.9.2p290 :021 > array2.first.object_id
=> 5232600
Does that help?
Sam
···
On 20/12/11 08:48, Nick Sandberg wrote:
I was working a project Euler problem and noticed that when I used this
code:
array1 = ["a", "b", "c", "d", "e"]
array2 = Array.new
array2<< array1
array1.clear
p array2
[] is my output. But, when I tried:
array1 = ["a", "b", "c", "d", "e"]
array2 = Array.new
array2<< array1
array1 =
p array2
[["a", "b", "c", "d", "e"]] is my output. I am not understanding why
clearing array1 is changing array2, but replacing the value of array1 is
having no effect.
(btw, using ruby 1.9.2p180)