This great tip allows you to recursively set hash value - really useful thing when you have to generate complicated hash.
One gotcha that i found about this is, that after generating SuperHash instance you must remember about reseting the default value of this hash.
Consider this:
class SuperHash < Hash
def initialize
super { |h, k| h[k] = SuperHash.new }
end
end
> suuper = SuperHash.new #=> {}
> suuper['mad']['sheep'] = false
> suuper['mad']['sheep'] #=> false
> suuper['mad']['cow'] #=> {}
> supper['calm']['sheep'] #=> {}
Notice that every undefined key, no matter how deeply nested will return empty hash instead of nil. This was a bit misleading for me since i used SuperHash instance to check complex conditions
> !!{} #=> true
Whatever i did, all conditions were always true :)
The solution of course w’d be to reset SuperHash default after generating full structure:
> suuper = SuperHash.new #=> {}
> suuper['mad']['sheep'] = false
> suuper.default = nil #=> nil
> supper['calm']#=> nil
However, as my colleague pointed out, reseting default only on suuper wont fix the issue, since nested hashes inside still have their own defaults. What we need to do is complete rewrite of our superhash back to hash again. This can be easily achievied with this:
> suuper = SuperHash.new #=> {}
> suuper['mad']['sheep'] = false #=> false
> suuper = {}.update(suuper)
> supper['calm'] #=> nil
> suuper['mad']['cow'] #=> nil
> supper['calm']['sheep'] #=> Error
And now we are golden :)