module Functional::PatternMatching::ClassMethods

Class methods added to a class that includes {Functional::PatternMatching} @!visibility private

Public Instance Methods

_() click to toggle source

@!visibility private

# File lib/functional/pattern_matching.rb, line 93
def _()
  UNBOUND
end
__define_method_with_matching__(function) click to toggle source

@!visibility private define an arity -1 function that dispatches to the appropriate pattern match variant or raises an exception

Calls superclass method
# File lib/functional/pattern_matching.rb, line 125
def __define_method_with_matching__(function)
  define_method(function) do |*args, &block|
    begin
      # get the collection of matched patterns for this function
      # use owner to ensure we climb the inheritance tree
      match = __pattern_match__(self.method(function).owner, function, args, block)
      if match
        # call the matched function
        argv = __unbound_args__(match, args)
        self.instance_exec(*argv, &match.body)
      elsif defined?(super)
        # delegate to the superclass
        super(*args, &block)
      else
        raise NoMethodError.new("no method `#{function}` matching "\
          "#{args} found for class #{self.class}")
      end
    end
  end
end
__function_pattern_matches__() click to toggle source

@!visibility private

# File lib/functional/pattern_matching.rb, line 147
def __function_pattern_matches__
  @__function_pattern_matches__ ||= Hash.new
end
__pattern_arity__(pat) click to toggle source

@!visibility private

# File lib/functional/pattern_matching.rb, line 162
def __pattern_arity__(pat)
  r = pat.reduce(0) do |acc, v|
    if v.is_a?(Hash) 
      ub = v.values.count { |e| e == UNBOUND }
      # if hash have UNBOUND then treat each unbound as separate arg
      # alse all hash is one arg
      ub > 0 ? acc + ub : acc + 1
    elsif v == ALL || v == UNBOUND || v.is_a?(Class)
      acc + 1
    else
      acc
    end
  end
  pat.last == ALL ? -r : r
end
__register_pattern__(function, *args, &block) click to toggle source

@!visibility private

# File lib/functional/pattern_matching.rb, line 152
def __register_pattern__(function, *args, &block)
  block = Proc.new{} unless block_given?
  pattern = FunctionPattern.new(function, args, block)
  patterns = self.__function_pattern_matches__.fetch(function, [])
  patterns << pattern
  self.__function_pattern_matches__[function] = patterns
  pattern
end
defn(function, *args, &block) click to toggle source

@!visibility private

# File lib/functional/pattern_matching.rb, line 98
def defn(function, *args, &block)
  unless block_given?
    raise ArgumentError.new("block missing for definition of function `#{function}` on class #{self}")
  end

  # Check that number of free variables in pattern match method's arity
  pat_arity = __pattern_arity__(args)
  unless pat_arity == block.arity
    raise ArgumentError.new("Pattern and block arity mismatch: "\
                              "#{pat_arity}, #{block.arity}")
  end

  # add a new pattern for this function
  pattern = __register_pattern__(function, *args, &block)

  # define the delegator function if it doesn't exist yet
  unless self.instance_methods(false).include?(function)
    __define_method_with_matching__(function)
  end

  # return a guard clause to be added to the pattern
  GuardClause.new(function, self, pattern)
end