Created
January 12, 2015 00:24
-
-
Save dibayendu/6c80bd26ea34eb1ab798 to your computer and use it in GitHub Desktop.
Hash to OpenStruct and vice-versa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Conversion | |
module Boolean; end | |
class TrueClass; include Boolean; end | |
class FalseClass; include Boolean; end | |
def to_openstruct(hashed_object) | |
case hashed_object | |
when Hash | |
boolean_methods = [] | |
hashed_object.each do |k, v| | |
hashed_object[k] = to_openstruct(v) | |
boolean_methods << k if v.is_a?(Boolean) # for boolean methods e.g. :run, :run? | |
end | |
instance = OpenStruct.new(hashed_object) | |
boolean_methods.each { |m| instance.class.send(:define_method, "#{m}?", lambda {hashed_object[m]}) } | |
instance | |
when Array | |
hashed_object.map! { |i| to_openstruct(i) } | |
else | |
hashed_object | |
end | |
end | |
def to_hash(openstruct_object) | |
case openstruct_object | |
when Array | |
openstruct_object.map! {|i| to_hash(i) } | |
when OpenStruct | |
hashed_object = {} | |
method_names = (openstruct_object.public_methods - OpenStruct.public_instance_methods) | |
method_names = method_names.map!(&:to_s).map{|s| s.delete('=')}.uniq | |
method_names.each { |m| hashed_object[m.to_sym] = to_hash(openstruct_object.send(m)) } | |
hashed_object | |
else Object | |
openstruct_object | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe Conversion do | |
include Conversion | |
let(:openstruct_object) do | |
OpenStruct.new({ | |
total: 3, | |
content: OpenStruct.new({ | |
japan: OpenStruct.new({ currency: 'Yen', continent: 'Asia', nuclear_plant: true }), | |
england: OpenStruct.new({ currency: 'Sterling', continent: 'Europe', nuclear_plant: true }), | |
australia: OpenStruct.new({ currency: 'Australian Dollar', continent: 'Asia Pacific', nuclear_plant: false }) | |
}), | |
car_makers: ['honda', 'jaguar', 'holden'] | |
}) | |
end | |
let(:hash_object) do | |
{ | |
total: 3, | |
content: { | |
japan: { currency: 'Yen', continent: 'Asia', nuclear_plant: true }, | |
england: { currency: 'Sterling', continent: 'Europe', nuclear_plant: true }, | |
australia: { currency: 'Australian Dollar', continent: 'Asia Pacific', nuclear_plant: false } | |
}, | |
car_makers: ['honda', 'jaguar', 'holden'] | |
} | |
end | |
it 'converts openstruct to hash' do | |
expect(to_hash(openstruct_object)).to eql(hash_object) | |
end | |
it 'converts hash to openstruct' do | |
expect(to_openstruct(hash_object)).to eql(openstruct_object) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment