Why does insert / delete on one array also modify another?

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 another variable ( temp ), why does the temp variable change after using delete_at to arry ? Is there a way to store the value of an array with an insert object permanently?

Here is a 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] 
+4
source share
3 answers

When you assign an array to a new variable, the array itself is not copied, but only a reference to this array is set. If you want to save the original array into a new variable, you need to clone the array. You can do this via dup .

 temp = arry.dup 
+6
source

This is because you are making the temp variable pointing to the same object as the arry variable. To do what you want, you must make a copy of this object:

 temp = arry.dup 
+1
source

I just feel in the right mood to tell something more than the previous commentators, because some time ago I had almost the same headache with all these materials related to the transmission-link. So:

Ruby variables are actually references to basic objects inside a Ruby virtual machine. They are passed to the function "by value", which means that when you execute function(arg) , function actually gets a copy of the reference to the memory object. Thus, function gets a valid object reference, which is arg and a copy of the arg link. When you perform some action on an object referenced by arg or copy, you successfully modify that object directly. (But when you work directly with links, everything happens only with links, so the copied link inside the function can even be deleted, which does not affect the original link 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] 

This is because by saying array_ref0 = [1,2,3] you reassigned the reference to the new object, but array_ref1 still refers to the old object, which is alive, because> = 1 refers to it (not to mention 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 up a bit.

I am not telling you that #dup is your array, because previous commentators have given you comprehensive practical answers.

+1
source

Source: https://habr.com/ru/post/1486512/


All Articles