読者です 読者をやめる 読者になる 読者になる

ネストしたHashからOpenStructを作る

HashからOpenStructを作成する場合、

pry(main)> OpenStruct.new({hoge: 1})
=> #<OpenStruct hoge=1>
pry(main)> OpenStruct.new({hoge: 1}).hoge
=> 1

のようにすればよい。 しかしネストしたHashだと以下のようになる。

pry(main)> OpenStruct.new({hoge: {fuga: 2}})
=> #<OpenStruct hoge={:fuga=>2}>
pry(main)> OpenStruct.new({hoge: {fuga: 2}}).hoge
=> {:fuga=>2}
pry(main)> OpenStruct.new({hoge: {fuga: 2}}).hoge.fuga
NoMethodError: undefined method `fuga' for {:fuga=>2}:Hash
from (pry):29:in `<main>'

やりたいのは、 再帰的にOpenStructを適用して、 xxx.hoge.fugaでアクセスできるようにすること。 https://github.com/aetherknight/recursive-open-struct のようなgemを使えばできるが、 以下のようにいったんJSONに変換すると簡単に再帰的にOpenStructに変換してくれる。

pry(main)> h = {hoge: {fuga: 2}}
=> {:hoge=>{:fuga=>2}}
pry(main)> JSON.parse(h.to_json, object_class: OpenStruct)
=> #<OpenStruct hoge=#<OpenStruct fuga=2>>
pry(main)> o = JSON.parse(h.to_json, object_class: OpenStruct)
=> #<OpenStruct hoge=#<OpenStruct fuga=2>>
pry(main)> o.hoge.fuga
=> 2