From: Pit Capitain Date: 2002-09-13T17:51:48+09:00 Subject: Re: not grasping the method overloading/multi-dispatch thing On 13 Sep 2002, at 7:22, Paul Brannan wrote: > On Fri, Sep 13, 2002 at 05:41:20AM +0900, Rich Kilmer wrote: > > def fred(*args) > > case args.collect { |a| a.type} > > when [Float, Fixnum, String] > > f, i, s = args > > # ... > > With this mechanism, how can I add a new signature to the list? What > if I want to extend fred() to work with GMP Integers? Paul, in the former thread Robert Feldt showed another implementation in [ruby-talk:26792] that lets you do what you asked for. I came up with the following implementation based on Robert's code. Don't know why I didn't post it to the list then. Maybe because it still lacks some necessary features. Regards, Pit class Module @@dispatch_db = Hash.new def overload( meth, *classes, &code ) ( @@dispatch_db[ [ self, meth ] ] ||= {} )[ classes ] = code unless instance_methods.include?( meth ) class_eval <<-EOS def #{meth}( *args ) Module.dispatch( #{self}, :#{meth}, *args ) end EOS end end def dispatch( cls, meth, *args ) @@dispatch_db[ [ cls, meth ] ].each do | classes, code | catch( :nomatch ) do classes.size.times do | i | begin next if classes[ i ] === args[ i ]; rescue; end throw( :nomatch ) end return code[ *args ] end end raise "dispatch error" end end Test: class C overload :m, String, Integer do | s, i | puts "m String, Integer called with #{s} and #{i}" end end c = C.new c.m( "Test", 15 ) # --> String, Integer begin c.m( 2, "Test" ) rescue puts $! end # --> dispatch error class C overload :m, Integer, String do | i, s | puts "m Integer, String called with #{i} and #{s}" end end c.m( 2, "Test" ) # --> Integer, String class C overload :m, 0..9, String do | i, s | puts "m Digit, String called with #{i} and #{s}" end end c.m( 2, "Test" ) # --> Digit, String c.m( 20, "Test" ) # --> Integer, String