Skip to content

Instantly share code, notes, and snippets.

@purp
Created February 21, 2016 05:52
Show Gist options
  • Save purp/8208e2dc21a4da03b229 to your computer and use it in GitHub Desktop.
Save purp/8208e2dc21a4da03b229 to your computer and use it in GitHub Desktop.
MappedOpenStruct: useful for hashes from JSON with crappy keys
require 'ostruct'
class MappedOpenStruct < OpenStruct
MAP = {}
def initialize(hash=nil)
super
add_mapped_methods
end
private
def add_mapped_methods
return if self.class::MAP.nil?
self.class::MAP.each_pair do |key, value|
add_mapped_method(key.to_sym, value.to_sym)
end
end
def add_mapped_method(new_name, old_name)
if respond_to?(old_name) && !respond_to?(new_name)
define_singleton_method(new_name) { @table[old_name] }
end
if respond_to?("#{old_name}=") && !respond_to?("#{new_name}=")
define_singleton_method("#{new_name}=") { |x| modifiable[old_name] = x }
end
end
end
class Foo < MappedOpenStruct
MAP = {:foobie => :fb}
end
foo = Foo.new(fb: 2, df: 12)
# => #<Foo fb=2, df=12>
# Same same
foo.fb # => 2
foo.foobie # => 2
foo.foobie = 5
foo.fb # => 5
# Doesn't pollute original hash with new keys
foo.to_h # => {:fb=>5, :df=>12}
@purp
Copy link
Author

purp commented Feb 21, 2016

I find myself dealing with JSON APIs a lot. They often have key names which aren't very expressive or intuitive.

This trivial class gives me an object that maps better method names onto the crappy key names without polluting the underlying hash, making it easy to work with and easy to re-serialize to JSON as needed (ex. foo.to_h.to_json)

There's probably a better way to do this, but I've never found it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment