From: Rich Kilmer Date: 2001-11-29T14:05:00+09:00 Subject: [ruby-talk:26861] Re: overload possible? excellent idea...how about this refactoring... module Overload def overload(args, *types) return if args.length != types.length args.each_index {|i| return if args[i].type.to_s != types[i].to_s} yield *args end def invalid_signature(args) raise TypeError, "Invalid Signature: #{args.collect {|a| a.type.to_s}.join(', ')}" end end if __FILE__ == $0 class Fred include Overload def hello(*args) overload(args, :Fixnum, :String, :Float) do |i, s, f| puts "(Fixnum, String, Float) -> [ #{i}, \"#{s}\", #{f} ]" return "1" end overload(args, :String, :Fixnum) do |i, s| puts "(String, Fixnum) -> [ \"#{s}\", #{i} ]" return "2" end invalid_signature(args) end end f = Fred.new puts "f1 = "+f.hello(123, "hello", 123.456) puts "f2 = "+f.hello("hello", 123) begin f.hello("abc", "def") rescue TypeError puts "f3 = "+$! end end > -----Original Message----- > From: nobu.nokada@softhome.net [mailto:nobu.nokada@softhome.net] > Sent: Wednesday, November 28, 2001 10:50 PM > To: ruby-talk ML > Subject: [ruby-talk:26860] Re: overload possible? > > > At Thu, 29 Nov 2001 08:13:36 +0900, > Harry Ohlsen wrote: > > It IS a little messy, though, in that you have to sacrifice a class > > variable for the return value. Hmmm ... maybe Robert's version > > is looking simpler now :-). > > What about this. > > module Overload > class Argument > Separator = ",".freeze > attr_reader :signature > def initialize(sig, args) > @signature = sig > @arguments = args > end > def dispatch(*types, &block) > if @signature == types.join(Separator) > throw :dispatched, yield(*@arguments) > end > end > end > > def overload(args) > args = Argument.new(args.collect {|a| > a.type.to_s}.join(Argument::Separator), args) > catch(:dispatched) { > yield args > raise TypeError, "bad set of arguments, #{args.signature}" > } > end > end > > if __FILE__ == $0 > class Fred > include Overload > > def hello(*args) > overload(args) do |args| > args.dispatch(:Fixnum, :String, :Float) do > |i, s, f| > puts "(Fixnum, String, Float) -> [ #{i}, \"#{s}\", #{f} ]" > "1" > end > args.dispatch(:String, :Fixnum) do > |i, s| > puts "(String, Fixnum) -> [ \"#{s}\", #{i} ]" > "2" > end > end > end > > end > > f = Fred.new > > puts "f1 = "+f.hello(123, "hello", 123.456) > puts "f2 = "+f.hello("hello", 123) > begin > f.hello("abc", "def") > rescue TypeError > puts "f3 = "+$! > end > end > > Nobu Nakada