Sha256: 4e8880a41acfeed5d16137c99d1ba99bbdeec8d32c3e8a0f2e32500c5601ec46
Contents?: true
Size: 1.87 KB
Versions: 1
Compression:
Stored size: 1.87 KB
Contents
module Ataulfo class PatternMatching class Var < Struct.new(:value); end class Body def initialize(vars, other_self) @other_self = other_self vars.each do |k, v| define_singleton_method(k) { v.value } end end def method_missing(method_name, *args, &block) @other_self.send method_name, *args, &block end end class Matcher def initialize(object, pattern) @object = object @pattern_vars = pattern.select { |_, v| v.is_a? Var } inner_matches = pattern.select { |_, v| v.is_a? Hash } fixed_values = pattern.select { |_, v| !v.is_a?(Var) && !v.is_a?(Hash) } @object_respond_to_methods = pattern.keys.all? { |k| @object.respond_to? k } @object_answers_right_values = fixed_values.all? { |k, v| @object.send(k) == v } @matchers = inner_matches.map { |k, v| Matcher.new(object.send(k), v) } end def matches? @matchers.all?(&:matches?) if @object_respond_to_methods && @object_answers_right_values end def fill_vars @pattern_vars.each { |k, v| v.value = @object.send k } @matchers.each(&:fill_vars) end end def initialize(object, other_self) @object = object @other_self = other_self @context_vars = { } end def like(pattern, &block) matcher = Matcher.new(@object, pattern) return unless matcher.matches? matcher.fill_vars Body.new(@context_vars, @other_self).instance_eval(&block) @context_vars = { } end def method_missing(method_name, *_) # The line below also returns the "Var" to the # pattern. That makes it a collector parameter # already distributed where it belongs to. @context_vars[method_name] = Var.new end end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
ataulfo-1.0.1 | lib/ataulfo/pattern_matching.rb |