Skip to content

Instantly share code, notes, and snippets.

@jhoffner
Created September 7, 2012 15:54
Show Gist options
  • Save jhoffner/3667372 to your computer and use it in GitHub Desktop.
Save jhoffner/3667372 to your computer and use it in GitHub Desktop.
Make any hash dynamic (so that you can access its hash values as properties)
class Hash
#
# Makes the hash dynamic, allowing its hash values to be accessed as if they were properties on the object.
#
def make_dynamic(cascade = false, allow_dynamic_new_properties = false)
self.extend(DynamicAttrs) unless is_a? DynamicAttrs
@allow_dynamic_new_properties = allow_dynamic_new_properties
if cascade
self.each do |key, val|
if val.is_a? Hash
val.make_dynamic cascade, allow_dynamic_new_properties
elsif val.is_a? Array
val.map {|v| v.make_dynamic(cascade, allow_dynamic_new_properties) if v.is_a? Hash}
end
end
end
self
end
module DynamicAttrs
def method_missing(key, *args)
text = key.to_s
# if setter method
if (text[-1,1] == '=' and args.length == 1)
text = text.chop
# if there is already a text version of the key then set that version
if self.key? text
self[text] = args[0]
# otherwise use the sym version
elsif self.key? text.to_sym or @allow_dynamic_new_properties
self[text.to_sym] = args[0]
else
super(key, *args)
end
elsif args.length == 0
#if a text version of the key is already set
if self.key? text
self[text]
# else use the symbol version of the key
elsif self.key? key
self[key]
else
super(key, *args)
end
else
super(key, *args)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment