From: Robert Feldt Date: 2001-11-28T23:29:04+09:00 Subject: [ruby-talk:26792] Re: overload possible? On Wed, 28 Nov 2001, ts wrote: > >>>>> "W" == Wyss Clemens writes: > > W> No, UNLESS you ask Guy Decoux (ts) to give you his *extension* > > No, no. He want the dispatch on the *number* of arguments which personnaly > I don't like. I prefer the dispatch on the *type* of arguments. > > Like said in [ruby-talk:26788] it's easy to have dispatch on the number of > arguments. > And since this request is quite common below is some code for creating the dispatcher automagically. I'm not very fond of the philosophy in doing this, the code is not elegant and can probably be much shorter and its probably buggy but since people keep asking stuff like this, why not? It can dispatch both on type or number. Regards, Robert class Module private @@dispatch_db = Hash.new def dispatch(targetMethodId, methodId, dispatchSpec) insert_db(targetMethodId, methodId, dispatchSpec) create_dispatch_method(methodId) end def insert_db(targetMethodId, methodId, dispatchSpec) key = [self, methodId] h = @@dispatch_db[key] || Hash.new h[dispatchSpec] = targetMethodId # Will overwrite previous w. same hash! @@dispatch_db[key] = h end def create_dispatch_method(methodId) body = "" d = @@dispatch_db[[self, methodId]].sort do |a,b| if Array === a[0] Array === b[0] ? (a[0].length <=> b[0].length) : -1 else Array === b[0] ? 1 : a[0] <=> b[0] end end d.each_with_index do |(spec, target), i| body += <<-EOS #{i == 0 ? 'if' : 'elsif'} #{spec_to_code(spec)} #{target.to_s}(*args) EOS end class_eval <<-EOS def #{methodId.to_s}(*args) #{body} else raise "Could not dispatch" end end EOS end def spec_to_code(spec) if Integer === spec "args.length == #{spec}" elsif Array === spec i = -1 spec.map {|ts| "#{ts.inspect} === args[#{i+=1}]"}.join(" && ") end end end class Test def m1(a); puts "m1"; end def m2(a, b); puts "m2"; end def m_int(i); puts "m_int"; end dispatch :m1, :m, 1 dispatch :m2, :m, 2 dispatch :m_int, :m, [Integer] end t = Test.new t.m("1") t.m("1", "2") t.m(1)