def overload( name, *signiture, &block )
name = name.to_sym
if method_overloads.key?( name )
method_overloads[name][signiture] = block
else
method_overloads[name] = {}
method_overloads[name][signiture] = block
if method_defined?( name )
alias_method( "#{name}Generic", name )
has_generic = true
else
has_generic = false
end
define_method( name ) do |*args|
ovr = self.class.method_overloads["#{name}".to_sym]
sig = args.collect{ |a| a.class }
hit = nil
faces = ovr.keys.sort { |a,b| b.size <=> a.size }
faces.each do |cmp|
next unless cmp.size == sig.size
cmp.size.times { |i|
next unless cmp[i] < sig[i]
}
hit = cmp
end
if hit
ovr[hit].call(*args)
else
if has_generic
send( "#{name}Generic", *args )
else
raise NoMethodError
end
end
end
end
end