Converta um hash aninhado complexo em um objeto

Às vezes, em Ruby, precisamos converter um Hash em um objeto. Em vez de acessar chaves em Hash, queremos acessar atributos (métodos) em um objeto. OpenStruct fornece uma maneira fácil para nós para fazer isso: OpenStruct.new(hash).

Mas o que faremos se tivermos um Hash aninhado complexo com Arrays etc. OpenStruct não recursiva sobre Arrays e só funciona bem com uma estrutura plana. Eu encontrei vários Gems que tentam resolver esse problema, e tenho usado um em particular no ano passado: recursive-open-struct . Embora tenha funcionado bem no meu cenário específico, outros expressaram problemas. Como estava refatorando o código que fazia uso dessa Gem, pensei em tentar remover a dependência.

Eu descobri uma maneira mais simples de conseguir a mesma coisa sem a dependência de um Gem, e com muito menos código, e pensei que poderia compartilhá-la com a comunidade porque acho que é muito legal.

Podemos fazer com que o JSON faça o trabalho pesado para nós e instruí-lo a coagir os atributos aninhados em OpenStructs. Ele também respeitará Arrays.

Como JSON e OpenStruct estão na biblioteca padrão Ruby , não teremos dependências de terceiros.

Primeiro, precisamos exigir estas duas bibliotecas:

require 'json'
require
'ostruct'

Vamos criar um Hash aninhado complexo com Arrays:

hash = {:a=>1,:b=>[{:c=>2,:d=>[{:e=>3,:f=>4},{:e=>5,:f=>6}]},{:c=>4,:d=>[{:e=>7,:f=>8},{:e=>9,:f=>10}]},{:c=>6,:d=>[{:e=>11,:f=>12},{:e=>13,:f=>14}]}]}

Agora vamos converter o Hash em JSON:

json = hash.to_json
# => "{"a"":1