How do I copy a hash in Ruby?

Precipitous picture Precipitous · Nov 11, 2010 · Viewed 112.3k times · Source

I'll admit that I'm a bit of a ruby newbie (writing rake scripts, now). In most languages, copy constructors are easy to find. Half an hour of searching didn't find it in ruby. I want to create a copy of the hash so that I can modify it without affecting the original instance.

Some expected methods that don't work as intended:

h0 = {  "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1=Hash.new(h0)
h2=h1.to_hash

In the meantime, I've resorted to this inelegant workaround

def copyhash(inputhash)
  h = Hash.new
  inputhash.each do |pair|
    h.store(pair[0], pair[1])
  end
  return h
end

Answer

Mark Rushakoff picture Mark Rushakoff · Nov 11, 2010

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.