1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
module Keys_to_Meths def method_missing(meth, *args) if meth.to_s[-1] == 61 #if last char is an equal sign key = self.keys.select{|key| key.to_s == meth.to_s[0...-1]}[0] key ? self[key] = args[0] : raise("undefined key '#{meth}'") else key = self.keys.select{|key| key.to_s == meth.to_s}[0] key ? self[key] : raise("undefined key '#{meth}'") end end end class Hash def keys_to_meths self.each_key {|key| if self.methods.include?(key.to_s) then raise("key '#{key.to_s}' included in Hash method list") end} extend Keys_to_Meths end end =begin Example: hsh = {:one=>1, "two"=>2, "tres"=>3} hsh.keys_to_meths hsh.two # => 2 hsh.two = "t-dubble-izzo" # => "t-dubble-izzo" p hsh # => {:one=>1, "two"=>"t-dubble-izzo", "three"=>3} Fckup: String and Symbols mess up keys hsh = {:one=>1, "one"=>"uno"} hsh.keys_to_meths hsh.one # => 1 hsh.one = "GARBLE" # => "t-dubble-izzo" p hsh # => {:one=>"GARBLE", "one"=>"uno"} =end
Refactorings
No refactoring yet !
Eloy Duran
June 16, 2008, June 16, 2008 23:36, permalink
Why not use OpenStruct, am I missing something?
1 2 3 4 5
require 'ostruct' o = OpenStruct.new({'one' => 1, :two => 2}) p o.one # => 1 p o.two # => 2
Drew Olson
July 2, 2008, July 02, 2008 18:47, permalink
I agree with Eloy, but if you want to roll your own:
1 2 3 4 5 6 7 8 9 10
class Hash def method_missing(name,*args,&block) if self.has_key?(name) self.class.send(:define_method,name.to_s) do self[name] end self.send(name) end end end
Drew Olson
July 2, 2008, July 02, 2008 18:52, permalink
Updated my code to add methods to the singleton class rather than to Hash itself.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
class Hash def method_missing(name,*args,&block) if self.has_key?(name) (class << self; self; end).send(:define_method,name.to_s) do self[name] end self.send(name) end end end # Usage h = {:a => "a", :b => "b"} puts h.a puts h.b
/no comment/
>_>