From: ara.t.howard@... Date: 2006-07-18T02:08:14+09:00 Subject: Re: Save me from the method_missing On Tue, 18 Jul 2006 transfire@gmail.com wrote: > Yes, I do constrain the config keys to single word case insensitive strings. > Unfortuate I just don't see a nicer way. "y[:a][:b][:c]" just lacks all > elegance. And path notation (y/:a/:b/:c) while a _little_ better can't use > setting at the end (eg. y/:a/:b/:c = x). So what else is there? brainstorming: harp:~ > cat a.rb require 'yaml' class Config < ::Hash def self.new(yml) super().update YAML.load(yml.to_s) end end def Config(*a, &b) Config.new(*a, &b) end c = Config %( a: b: c: 42 ) # # just an idea # class Config < ::Hash def munge_keys *keys keys.compact! keys.flatten! keys.map!{|key| key.to_s.strip.split %r/\s/} keys end def [] *keys keys = munge_keys keys h = self nil while Hash === (h = h.fetch keys.shift.to_s) h end def []= *argv v, keys = argv.pop, argv keys = munge_keys keys h, h2, k = self, nil, nil h = h2 while Hash === (h2 = h.fetch(k = keys.shift.to_s)) h[k] = v end end p c[ :a, :b, :c ] c[ :a, :b, :c ] = 'forty-two' p c[ :a, :b, :c ] p c # # another, sillier one # class Config alias_method '^', '[]' end p c ^ %w( a b c ) harp:~ > ruby a.rb 42 "forty-two" {"a"=>{"b"=>{"c"=>"forty-two"}}} "forty-two" >> what do you mean 'iffy' exactly? > > Well, for instance. If a public method is added to Kernel or Object (or > any subclass for that matter) it will show up in ones class and block > out method_missing. i see three ways to get around this: a) use block form methods obj.configure{ # push method_missing handler and dsl methods onto stack # instance_eval the block # pop them off } so obj.configure{ a 4 b 2 } this gives you a chance to 'clean-out' the obj each time. b) use block form with blank slate proxy obj.configure{ # setup blank-slate proxy # instance_eval the block on proxy! # copy all state from proxy into object } c) use block form with an easily identifiable method name. i do this in my xx html/xml generation lib where puts xhtml_{ p_{ 'note that the "p" tag works! } b_{ i_{ u_{ "bold-italic-underline } } } } i can filter __only__ those methods ending in '_'. this has many advantages: - easy to distiguish ruby's methods like 'p' from html methods like 'p_' - easy to grep for 'special' methods in you source. i realize none of these really apply to a config style class. > >> that the list of 'require' methods seems to change every few months? > > Not sure what you mean. gsub/require/required/ meaning __id__, __send__, et al. cheers. -a -- suffering increases your inner strength. also, the wishing for suffering makes the suffering disappear. - h.h. the 14th dali lama