module Matchete

Constants

Any
None

Public Class Methods

included(klass) click to toggle source
# File lib/matchete.rb, line 5
def self.included(klass)
  klass.extend ClassMethods
  klass.instance_variable_set "@methods", {}
  klass.instance_variable_set "@default_methods", {}
end

Public Instance Methods

call_overloaded(method_name, args: [], kwargs: {}) click to toggle source
# File lib/matchete.rb, line 79
def call_overloaded(method_name, args: [], kwargs: {})
  handler = find_handler(method_name, args, kwargs)

  if kwargs.empty?
    handler.bind(self).call *args
  else
    handler.bind(self).call *args, **kwargs
  end
  #insane workaround, because if you have
  #def z(f);end
  #and you call it like that
  #empty = {}
  #z(2, **empty)
  #it raises wrong number of arguments (2 for 1)
  #clean up later
end
find_handler(method_name, args, kwargs) click to toggle source
# File lib/matchete.rb, line 96
def find_handler(method_name, args, kwargs)
  guards = self.class.instance_variable_get('@methods')[method_name].find do |guard_args, guard_kwargs, _|
    match_guards guard_args, guard_kwargs, args, kwargs
  end

  if guards.nil?
    default_method = self.class.instance_variable_get('@default_methods')[method_name]
    if default_method
      default_method
    else
      raise NotResolvedError.new("No matching #{method_name} method for args #{args}")
    end
  else
    guards.last
  end
end
match_guard(guard, arg) click to toggle source
# File lib/matchete.rb, line 124
def match_guard(guard, arg)
  case guard
    when Module
      arg.is_a? guard
    when Symbol
      if guard.to_s[-1] == '?'
        send guard, arg
      else
        guard == arg
      end
    when Proc
      instance_exec arg, &guard
    when Regexp
      arg.is_a? String and guard.match arg
    when Array
      arg.is_a?(Array) and
      guard.zip(arg).all? { |child_guard, child| match_guard child_guard, child }
    else
      if guard.is_a?(String) && guard[0] == '#'
        arg.respond_to? guard[1..-1]
      else
        guard == arg
      end
  end
end
match_guards(guard_args, guard_kwargs, args, kwargs) click to toggle source
# File lib/matchete.rb, line 113
def match_guards(guard_args, guard_kwargs, args, kwargs)
  return false if guard_args.count != args.count ||
                  guard_kwargs.count != kwargs.count
  guard_args.zip(args).all? do |guard, arg|
    match_guard guard, arg
  end and
  guard_kwargs.all? do |label, guard|
    match_guard guard, kwargs[label]
  end
end