Created
June 6, 2011 19:27
-
-
Save boone/1010901 to your computer and use it in GitHub Desktop.
Ruby unexpected behavior when using .clone or .dup on a hash (or array)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Ruby unexpected behavior when using .clone or .dup on a hash (or array) | |
# create a hash and freeze it so it shouldn't be modified | |
MY_HASH = { :one => { :first => 'eins', :second => 'zwei' } }.freeze | |
puts MY_HASH.inspect # {:one=>{:first=>"eins", :second=>"zwei"}} | |
new_hash = MY_HASH.dup # copy the hash, unfrozen | |
new_hash[:one][:second] = 'dos' | |
puts new_hash.inspect # {:one=>{:first=>"eins", :second=>"dos"}} | |
# original hash should not be modified, but it is! | |
puts MY_HASH.inspect # {:one=>{:first=>"eins", :second=>"dos"}} | |
# this happens apparently because hash copies are "shallow" and only contain pointers to values | |
# a "deep" copy requires ugliness using Marshal | |
MY_HASH2 = { :one => { :first => 'eins', :second => 'zwei' } }.freeze | |
puts MY_HASH2.inspect # {:one=>{:first=>"eins", :second=>"zwei"}} | |
new_hash2 = Marshal.load(Marshal.dump(MY_HASH2)) | |
new_hash2[:one][:second] = 'dos' | |
puts new_hash2.inspect # {:one=>{:first=>"eins", :second=>"dos"}} | |
# now the original hash is intact: | |
puts MY_HASH2.inspect # {:one=>{:first=>"eins", :second=>"zwei"}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment