Hashes of Hashes Idiom in Ruby?
Autovivification, as it's called, is both a blessing and a curse. The trouble can be that if you "look" at a value before it's defined, you're stuck with this empty hash in the slot and you would need to prune it off later.
If you don't mind a bit of anarchy, you can always just jam in or-equals style declarations which will allow you to construct the expected structure as you query it:
((h ||= { })['w'] ||= { })['z']
You can pass the Hash.new
function a block that is executed to yield a default value in case the queried value doesn't exist yet:
h = Hash.new { |h, k| h[k] = Hash.new }
Of course, this can be done recursively. There's an article explaining the details.
For the sake of completeness, here's the solution from the article for arbitrary depth hashes:
hash = Hash.new(&(p = lambda{|h, k| h[k] = Hash.new(&p)}))
The person to originally come up with this solution is Kent Sibilev.