module PatternMatching

Constants

ALL
UNBOUND
VERSION

Protected Class Methods

included(base) click to toggle source
# File lib/pattern_matching.rb, line 80
def self.included(base)

  class << base

    public

    def _() # :nodoc:
      return UNBOUND
    end

    def defn(func, *args, &block)
      unless block_given?
        raise ArgumentError.new("block missing for definition of function `#{func}` on class #{self}")
      end

      pattern = __add_pattern_for__(func, *args, &block)

      unless self.instance_methods(false).include?(func)

        define_method(func) do |*args, &block|
          result, match = PatternMatching.__pattern_match__(self.method(func).owner, func, args, block)
          if result == :ok
            # if a match is found call the block
            argv = PatternMatching.__unbound_args__(match, args)
            return self.instance_exec(*argv, &match[1])
          else # if result == :nodef || result == :nomatch
            begin
              super(*args, &block)
            rescue NoMethodError, ArgumentError
              raise NoMethodError.new("no method `#{func}` matching #{args} found for class #{self.class}")
            end
          end
        end
      end

      return GUARD_CLAUSE.new(func, self, pattern)
    end

    public

    def __function_pattern_matches__ # :nodoc:
      @__function_pattern_matches__ ||= Hash.new
    end

    def __add_pattern_for__(func, *args, &block) # :nodoc:
      block = Proc.new{} unless block_given?
      matchers = self.__function_pattern_matches__
      matchers[func] = [] unless matchers.has_key?(func)
      matchers[func] << [args, block, nil]
      return matchers[func].last
    end
  end
end