class Machete::Matchers::ArrayMatcher

Attributes

items[R]

Public Class Methods

new(items) click to toggle source
# File lib/machete/matchers.rb, line 61
def initialize(items)
  @items = items
end

Public Instance Methods

==(other) click to toggle source
# File lib/machete/matchers.rb, line 65
def ==(other)
  other.instance_of?(self.class) && @items == other.items
end
matches?(node) click to toggle source
# File lib/machete/matchers.rb, line 69
def matches?(node)
  return false unless node.is_a?(Array)

  match(@items, node)
end

Private Instance Methods

match(matchers, nodes) click to toggle source

Simple recursive algorithm based on the one for regexp matching described in Beatiful Code (Chapter 1).

# File lib/machete/matchers.rb, line 79
def match(matchers, nodes)
  if matchers.empty?
    nodes.empty?
  elsif !matchers[0].is_a?(Quantifier)
    matchers[0].matches?(nodes[0]) && match(matchers[1..-1], nodes[1..-1])
  else
    quantifier = matchers[0]

    # Too little elements?
    return false if nodes.size < quantifier.min

    # Make sure at least min elements match.
    matches_min = nodes[0...quantifier.min].all? do |node|
      quantifier.matcher.matches?(node)
    end
    return false unless matches_min

    # Now try to match the remaining elements. The shortest match wins.
    i = quantifier.min
    max = if quantifier.max
      [quantifier.max, nodes.size].min
    else
      nodes.size
    end
    while i <= max
      return true if match(matchers[1..-1], nodes[i..-1])

      matches_next = nodes[i...(i + quantifier.step)].all? do |node|
        quantifier.matcher.matches?(node)
      end
      return false unless matches_next

      i += quantifier.step
    end

    # No match found.
    false
  end
end