Reputation: 923
I have a question about using insert
and delete_at
with arrays. If I insert an element into an array (arry
) and then store that value in a different variable (temp
), why does the variable temp
change after I use delete_at
on arry
? Is there a way to store the value of the array with the insert object permanently?
Here is some sample code:
arry = [0,1,3,4]
# => [0, 1, 3, 4]
arry.insert(1,5)
# => [0, 5, 1, 3, 4]
temp = arry
# => [0, 5, 1, 3, 4]
arry.delete_at(1)
# => 5
temp
# => [0, 1, 3, 4]
Upvotes: 4
Views: 1309
Reputation: 4798
I'm just feeling in a right mood to tell something more than previous commenters, because some time ago I've had nearly the same headache with all this pass-reference-by-value stuff. So:
Ruby's variables are actually references to underlying objects inside Ruby's virtual machine. They are passed into functions 'by value', which means when you do function(arg)
, function
actually gets copy of reference to the memory object. So, function
gets a valid reference to object, which arg
and copy of arg
reference. When you perform some actions on object referenced by arg
or it's copy, you successfully modify directly that object. (But when you operate directly on references, things happen only to references, hence, copied reference inside function may even be deleted, which doesn't affect original reference or object. Consider this:
array_ref0 = [1,2,3] # actually, this reference represents array
array_ref1 = array_ref0
def f(arg); arg[0] = 0; end
f(array_ref0)
p array_ref0 # => [0,2,3]
p array_ref1 # => [0,2,3]
array_ref0 = [1,2,3]
p array_ref0 # => [1,2,3]
#but!
p array_ref1 # => [0,2,3]
That's because saying array_ref0 = [1,2,3]
you reassigned the reference to a new object, but array_ref1 still references the old object, which is alive because >=1 references reference to it (not going to talk much about GC here)
def g(arg); arg = nil; end
g(array_ref0)
p array_ref0 # => [1,2,3], because we only nil-ed copy of array_ref0.
Hope that cleared things a little.
I'm not telling you to #dup your array because previous commenters gave you comprehensive practical answers.
Upvotes: 1
Reputation: 19241
When you assign an array to a new variable, the array itself is not copied but only reference to that array is set. If you want to save original array to new variable, you need to clone the array You can do it via dup.
temp = arry.dup
Upvotes: 6
Reputation: 51151
It happens because you make temp
variable pointing at the same object as arry
variable. To do what you want, you should make copy of this object:
temp = arry.dup
Upvotes: 1