require 'ostruct'
class Object
def hash_to_ostruct(visited = [])
self
end
end
class Array
def hash_to_ostruct(visited = [])
map { |x| x.hash_to_ostruct(visited) }
end
end
class Hash
def hash_to_ostruct(visited = [])
os = OpenStruct.new
each do |k, v|
item = visited.find { |x| x.first.object_id == v.object_id }
if item
os.send("#{k}=", item.last)
else
os.send("#{k}=", v.hash_to_ostruct(visited + [ [self, os] ]))
end
end
os
end
end
hash = { "country" => {:a => "a"}, :population => 20_000_000 }
p hash.hash_to_ostruct