Hashes aninhados em rubi são um PITA. se em algum lugar ao longo do caminho uma de suas chaves estiver faltando / retornando um hash vazio, você terá uma ideia:
undefined method `[]' for nil:NilClass (NoMethodError)
Sim. irritante.
Eu tentei resolver esse problema criando este spinoff de ruby hash que aceita valores padrão para solicitações de busca de chave. Aqui está
class NestedHash < Hash
def [](value, default = NestedHash.new)
self.fetch(value, default)
end
def self.from_hash(other_hash)
nested_hash = NestedHash.new
other_hash.each_pair do |key, val|
if val.is_a?(Hash)
nested_hash[key] = NestedHash.from_hash(val)
else
nested_hash[key] = val
end
end
return nested_hash
end
end
# Setup a regular hash
h = NestedHash.new
h["elad"] = NestedHash.new
h["elad"]["adam"] = NestedHash.new
h["elad"]["adam"]["hungry"] = "always"
# Test non existing value
puts h["elad"]["miki"]["hungry", "no"] # => "no"
# Test Converstions from regular hashes
real_hash = {:elad => {:koko => :awesome}, :adam => {:moko => :no}}
nested = NestedHash.from_hash(real_hash)
# Missing Value
puts nested[:elad][:invalid_key, "not here"] # => "not here"
# Existing value
puts nested[:elad][:koko] # => "awesome"
também disponível como um resumo: https://gist.github.com/eladmeidar/5857066