Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to copy a ruby variable?

Tags:

variables

ruby

Maybe I've just been staring at my screen too long today, but something I think should be very basic is stumping me.

I'm trying to make a 'copy' of a variable so I can manipulate it without modifying the original.

# original var is set
foo = ["a","b","c"]

# i want a copy of the original var so i dont modify the original
bar = foo

# modify the copied var
bar.delete("b")

# output the values
puts bar # outputs: ["a","c"] - this is right
puts foo # outputs: ["a","c"] - why is this also getting modified?

I want foo not to be changed.

like image 608
Jason Varga Avatar asked Mar 16 '13 02:03

Jason Varga


3 Answers

foo and bar refer to the same object. To make bar refer to a different object, you have to clone foo:

bar = foo.clone
like image 125
Blender Avatar answered Oct 19 '22 03:10

Blender


You can use the dup method:

bar = foo.dup

This will return a copy of foo, so any changes you make to bar will not effect foo.

like image 29
Oleksi Avatar answered Oct 19 '22 05:10

Oleksi


In the below code you can see that foo and bar both are having the same object_id. Thus changing to the foo instance causes same reflection to see through the bar.

foo = ["a","b","c"]
#=> ["a", "b", "c"]

foo.object_id
#=> 16653048

bar = foo
#=> ["a", "b", "c"]

bar.object_id
#=> 16653048

bar.delete("b")
#=> "b"

puts bar
#a
#c
#=> nil

puts foo
#a
#c
#=> nil

See here also that I freeze the foo in effect the bar also has been frozen.

foo.freeze
#=> ["a", "c"]
foo.frozen?
#=> true
bar.frozen?
#=> true

Thus the right way is below :

bar = foo.dup
#=> ["a", "b", "c"]

foo.object_id
#=> 16450548

bar.object_id
#=> 16765512

bar.delete("b")
#=> "b"

print bar
#["a", "c"]=> nil

print foo
#["a", "b", "c"]=> nil

Cheers!!

like image 38
Arup Rakshit Avatar answered Oct 19 '22 03:10

Arup Rakshit