Skip to content

Instantly share code, notes, and snippets.

@boone
Created June 6, 2011 19:27
Show Gist options
  • Save boone/1010901 to your computer and use it in GitHub Desktop.
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)
# 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