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