Ken Bloom
10/1/2006 6:15:00 PM
Brian Mitchell wrote:
> On 10/1/06, Trans <transfire@gmail.com> 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