Take me home

Recursively doing stuff with hashes

Written by August Lilleaas, published August 31, 2008

It's assumed that by "recursive", one means that when a value in a hash contains another hash, do X on that hash as well.

class Hash
  def recursively(&block)
    each {|k, v| Hash === v ? v.recursively(&block) : yield(k, v) }
  end
end

This lets us do the following:

h = {:foo => "bar", :baz => {:srsly => "ye", :oh_hai => {:works => "indeed"}}}
h.recursively {|k, v| v.upcase! }
# => {:foo=>"BAR", :baz=>{:oh_hai=>{:works=>"INDEED"}, :srsly=>"YE"}}

SystemStackError: stack level too deep can be produced by having one of the keys refer to the hash in question, though, be careful.

h = {:foo => "bar", :maz => {:hai => "to you"}}
h[:oops] = h
# => {:oops=>{...}, :foo=>"bar", :maz=>{:hai=>"to you"}}

h.recursively {|k, v| v.upcase! }
# => SystemStackError: stack level too deep

Questions or comments?

Feel free to contact me on Twitter, @augustl, or e-mail me at august@augustl.com.