lib/matchete.rb in matchete-0.0.2 vs lib/matchete.rb in matchete-0.2.0

- old
+ new

@@ -30,10 +30,18 @@ def default(method_name) @default_methods[method_name] = instance_method(method_name) convert_to_matcher method_name end + def either(*guards) + -> arg { guards.any? { |g| match_guard(g, arg) } } + end + + def full_match(*guards) + -> arg { guards.all? { |g| match_guard(g, arg) } } + end + def supporting(*method_names) -> object do method_names.all? do |method_name| object.respond_to? method_name end @@ -44,26 +52,26 @@ define_method(method_name) do |*args, **kwargs| call_overloaded(method_name, args: args, kwargs: kwargs) end end end - + def call_overloaded(method_name, args: [], kwargs: {}) handler = find_handler(method_name, args, kwargs) - if handler.parameters.any? do |type, _| - [:key, :keyrest, :keyreq].include? type - end - handler.bind(self).call *args, **kwargs - else + + 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 - #a(2, **{e: 4}) + #empty = {} + #z(2, **empty) #it raises wrong number of arguments (2 for 1) - #clean later + #clean up later end 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 @@ -75,38 +83,44 @@ default_method else raise NotResolvedError.new("No matching #{method_name} method for args #{args}") end else - guards[2] + guards.last end end def match_guards(guard_args, guard_kwargs, args, kwargs) - return false if guard_args.count != args.count || guard_kwargs.count != kwargs.count + 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 def match_guard(guard, arg) + p case guard when Module arg.is_a? guard when Symbol send guard, arg when Proc - guard.call arg + 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 - guard == arg + if guard.is_a?(String) && guard[0] == '#' + arg.respond_to? guard[1..-1] + else + guard == arg + end end end end