Have a need to create method overloading, so I put together an
implementation. Curious what other think of it; how to improve it; or
do it a better way.

Thanks,
T.

# ---- overload.rb

class Module

  def method_overloads
    @method_overloads ||= {}
  end

  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 )
        #method_overloads[name][nil] = instance_method( name ) #true
        alias_method( "#{name}Generic", name )
        has_generic = true
      else
        has_generic = false
      end

      define_method( name ) do |*args|
        ovr = self.class.method_overloads[:"#{name}"]
        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 #ovr[nil]
            send( "#{name}Generic", *args )
            #ovr[nil].bind(self).call(*args)
          else
            raise NoMethodError
          end
        end

      end

    end

  end

end


#  _____         _
# |_   _|__  ___| |_
#   | |/ _ \/ __| __|
#   | |  __/\__ \ |_
#   |_|\___||___/\__|
#

class X

  def x
    "hello"
  end

  overload :x, Integer do |i|
    i
  end

  overload :x, String, String do |s1, s2|
    [s1, s2]
  end

end

x = X.new
p x.x
p x.x(1)
p x.x("a","b")