From: "kbloom@..." Date: 2006-10-02T03:20:05+09:00 Subject: Re: Caveats with #method_missing Brian Mitchell wrote: > On 10/1/06, Trans wrote: > > Even after the public/private send issue is resolved with #funcall, > > #send!, #instance_send or what ever is method decided upon, how will we > > be ablesto distinguish between a private and a public method call in > > method_missing? > > > > Also when delaing with writers, the need to do things like: > > > > def method_missing( sym, *args, &blk ) > > if sym.to_s =~ /=$/ > > @data[ sym.to_s.chomp('=').to_sym ] = args[0] > > > > Is, well... Blech! I'd like to see something like: > > > > def writer_missing( name, value ) > > @data[ name ] = value > > end > > > > Thoughts? > > T. > > I've thought of proposing something like define_method but for missing methods: > > # Just some rough ideas... > > class Example > define_missing_method /^find_\w+$/ do |sym, *args, &block| > puts "Handling #{sym}" > end > end > > ex1 = Example.new > > ex1.respond_to? :find_something #=> true > ex1.respond_to? :not_found #=> false > > We could probably extend a few methods around this as well: > > ex1.missing_methods # Maybe return patterns/strings > ex1.methods # We could possibly return something here.. big change > ex1.all_methods # This might be a better alternative for a combined list > > Both of these ideas should be simple enough to implement prototypes in > pure Ruby. I'll have to spend time on this and get some code that we > can play with. > > I do like the simpler method definition but I don't really like the > idea of having magically connected names. It would also mean we would > have problems around "method_missing" as a name. I would rather get > some nice helpers that hook into a much smarter method_missing system. > > Brian. Roll your own (or use mine). I decided here to pass the matchinfo, rather than the symbol, so that you could take advantage of match groups. Modify to suit. module MissingMethod def method_missing symbol,*args matchinfo=nil code=nil if self.class.methods_missing.any? do |pattern,code| matchinfo= pattern.match(symbol.to_s) end code.call(matchinfo,*args) { |*args| yield *args} else super end end module ClassMethods def define_missing_method pattern,&code methods_missing << [pattern,code] end def methods_missing @methods_missing ||= [] end end def self.included(other) other.extend(ClassMethods) end end class A include MissingMethod define_missing_method /^(.*)=/ do |matchinfo,newval| @data ||= Hash.new @data[matchinfo[1]] = newval end define_missing_method /^(.*)/ do |matchinfo| @data[matchinfo[1]] end end a=A.new a.myfunc="a" p a.myfunc