I am aware of this feature provided by ActiveSupport.
h = ActiveSupport::OrderedOptions.new
h.boy = \'John\'
h.girl = \'Mary\'
h.boy # => \'John\'
h.girl # =
If it’s just a small script it’s safe to extend Hash
itself
class Hash
def method_missing sym,*
fetch(sym){fetch(sym.to_s){super}}
end
end
method_missing
is a magic method that is called whenever your code tries to call a method that does not exist. Ruby will intercept the failing call at run time and let you handle it so your program can recover gracefully. The implementation above tries to access the hash using the method name as a symbol, the using the method name as a string, and eventually fails with Ruby's built-in method missing error.
For a more complex application, where adding this behavior to all hashes might break other code or third0party gems, use a module and extend each instance
module H
def method_missing sym,*
fetch(sym){fetch(sym.to_s){super}}
end
end
the = { answer: 42 }
the.extend(H)
the.answer # => 42
and for greater convenience you can even propagate the module down to nested hashes
module H
def method_missing sym,*
r = fetch(sym){fetch(sym.to_s){super}}
Hash === r ? r.extend(H) : r
end
end
the = { answer: { is: 42 } }
the.extend(H)
the.answer.is # => 42