module MultiDispatch::ClassMethods

Public Instance Methods

def_multi(_name, *args, &body) click to toggle source
# File lib/multi_dispatch/dispatch.rb, line 8
    def def_multi(_name, *args, &body)
#       _name = args.shift
      # closure (to prevent namespace pollution)
      multi_methods = {}

      # only at first invocation
      define_singleton_method :instance_multi_methods do 
        multi_methods.values.flatten
      end
      
      define_singleton_method :instance_multi_method do |name, *args|
        mthd = self.instance_multi_methods.select do |m| 
          m.match?(name, args) 
        end.sort_by { |m| m.match_distance(args) }.first
        unless mthd
          raise NoMethodError,
            "undefined method `#{name}' for class `#{singleton_class}'"
        end
        mthd
      end

      define_singleton_method :def_multi do |name, *args, &body|
        multi_methods[name] ||= []
        multi_methods[name].unshift(UnboundMultiMethod.new(name, *args, body ))
        if !method_defined?(name)
          define_method name do |*params|
            singleton_class.instance_multi_method(name, *params).
            bind(self).call(*params)
          end
        end
      end
      self.send(:def_multi, *([_name]+args), &body)
    end