December 31, 2010
I you already know how this infinite hash works then you are all set. If not read along.
If I want a hash to have a default value then that's easy.
h = Hash.new(0)
puts h['usa'] #=> 0
Above code will give me a fixed value if key is not found. If I want dynamic value then I can use block form.
h = Hash.new{|h,k| h[k] = k.upcase}
puts h['usa'] #=> USA
puts h['india'] #=> INDIA
If I want the default value to be a hash
then it seems easy but it falls apart
soon.
h = Hash.new{|h,k| h[k] = {} }
puts h['usa'].inspect #=> {}
puts h['usa']['ny'].inspect #=> nil
puts h['usa']['ny']['nyc'].inspect #=> NoMethodError: undefined method `[]' for nil:NilClass
In the above if a key is missing for h
then it returns a hash. However that
returned hash is an ordinary hash which does not have a capability of returning
another hash if a key is missing.
This is where default_proc
comes into picture.
hash.default_proc
returns the block which was passed to Hash.new
.
h = Hash.new{|h,k| Hash.new(&h.default_proc)}
puts h['usa']['ny']['nyc'].inspect #=> {}
If this blog was helpful, check out our full blog archive.