How do I copy a hash in Ruby?
The clone
method is Ruby's standard, built-in way to do a shallow-copy:
irb(main):003:0> h0 = {"John" => "Adams", "Thomas" => "Jefferson"}=> {"John"=>"Adams", "Thomas"=>"Jefferson"}irb(main):004:0> h1 = h0.clone=> {"John"=>"Adams", "Thomas"=>"Jefferson"}irb(main):005:0> h1["John"] = "Smith"=> "Smith"irb(main):006:0> h1=> {"John"=>"Smith", "Thomas"=>"Jefferson"}irb(main):007:0> h0=> {"John"=>"Adams", "Thomas"=>"Jefferson"}
Note that the behavior may be overridden:
This method may have class-specific behavior. If so, that behavior will be documented under the
#initialize_copy
method of the class.
As others have pointed out, clone
will do it. Be aware that clone
of a hash makes a shallow copy. That is to say:
h1 = {:a => 'foo'} h2 = h1.cloneh1[:a] << 'bar'p h2 # => {:a=>"foobar"}
What's happening is that the hash's references are being copied, but not the objects that the references refer to.
If you want a deep copy then:
def deep_copy(o) Marshal.load(Marshal.dump(o))endh1 = {:a => 'foo'}h2 = deep_copy(h1)h1[:a] << 'bar'p h2 # => {:a=>"foo"}
deep_copy
works for any object that can be marshalled. Most built-in data types (Array, Hash, String, &c.) can be marshalled.
Marshalling is Ruby's name for serialization. With marshalling, the object--with the objects it refers to--is converted to a series of bytes; those bytes are then used to create another object like the original.