Skip to content

Instantly share code, notes, and snippets.

@suhovius
Forked from Integralist/1. Success.rb
Created January 3, 2023 23:22
Show Gist options
  • Save suhovius/1525946c97896b2c184202a37f1bacd0 to your computer and use it in GitHub Desktop.
Save suhovius/1525946c97896b2c184202a37f1bacd0 to your computer and use it in GitHub Desktop.
How to clone a Hash (in Ruby) and modify the cloned hash without affecting the original object
# This is the ONLY way I've found that works
# All other suggested solutions (see below examples) don't actually work
# And as an extra bonus: this deep copies as well!
def deep_copy(o)
Marshal.load(Marshal.dump(o))
end
def test(some_data)
some_data.each { |k, v| some_data.tap { |d| d[k].upcase! } }
end
blah = { :foo => 'bar' }
blah_clone = blah.clone # cloning the hash so we affect the clone and not the original
test(blah_clone) # cloned hash has been changed as expected => {:foo=>"BAR"}
blah # shouldn't be touched but => {:foo=>"BAR"}
#########################################################################################
# I've also tried the following (straight copied from a stack overflow answer which is supposed to work but doesn't)...
def copyhash(inputhash)
h = Hash.new
inputhash.each do |pair|
h.store(pair[0], pair[1])
end
return h
end
original = { :key => 'foobar' }
test = copyhash(original)
test[:key].upcase!
test # => {:key=>"FOOBAR"}
original # => {:key=>"FOOBAR"}
#########################################################################################
# The following also doesn't work...
original = { :key => 'foobar' }
test = Hash[original]
original.object_id # => 2262
test.object_id # => 2268
test[:key].upcase! # => "FOOBAR"
test => {:key=>"FOOBAR"}
original => {:key=>"FOOBAR"}
#########################################################################################
# The following also doesn't work...
h0 = { "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1 = h0.inject({}) do |new, (name, value)|
new[name] = value;
new
end
h1["John"].upcase!
h0["John"] # => "ADAMS"
h1["John"] # => "ADAMS"
#########################################################################################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment