Class: Tree::Filter

Inherits:
Object
  • Object
show all
Defined in:
lib/modular_tree/filter.rb

Constant Summary collapse

ALL =
Filter.new

Instance Method Summary collapse

Constructor Details

#initialize(select_expr = nil, traverse_expr = nil, &block) ⇒ Filter

:call-seq:

Filter.new(select_expr, traverse_expr)
Filter.new(select_expr, &block)
Filter.new(&block)

Create a node filter. The filter is initialized by a select expression and a traverse expression. The select expression decides if the node should be given to the block (or submitted to an enumerator) and the traverse expression decides if the child nodes should be traversed recursively

The expressions can be a Matcher object or one of Matcher’s initializers: Proc, Symbol, Class, or an array of classes. In addition, select can be true, and traverse can be true, false, or nil. These values have special meanings:

when +select+ is
  true    Select always. This is the default
  false   This is an allowed value but it doesn't select any node

when +traverse+ is
  true    Traverse always. This is the default
  false   Traverse only if select didn't match # TODO: Never traverse to be able to use filters on children
  nil     Expects +select+ to be a Proc object that returns a [select,
          traverse] tuple of booleans

If the expression is a Proc object, it will be called with the current node as argument. If the return value is true, the node is selected/traversed and skipped otherwise. If the expression is a method name (Symbol), the method will be called on each node with no arguments. It is not an error if the method doesn’t exists on the a given node but the node is not selected/traversed. If the expression is a class or an array of classes, a given node matches if it is an instance of one of the classes and their subclasses

If a block is given, it is supposed to return a [select, traverse] tuple of booleans

Filters should not have side-effects because they can be used in enumerators that doesn’t execute the filter unless the enumerator is evaluated

TODO: Accept RegExp -> use to_s to match



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/modular_tree/filter.rb', line 46

def initialize(select_expr = nil, traverse_expr = nil, &block)
  if select_expr.nil? && block_given?
    @matcher = block
  else
    select_expr = true if select_expr.nil?
    select = Matcher.new(select_expr)
    traverse_expr = (block_given? ? block : true) if traverse_expr.nil?
    traverse = traverse_expr ? Matcher.new(traverse_expr) : !select
    @matcher = lambda { |node| [select.match?(node), traverse.match?(node)] }
  end
end

Instance Method Details

#match(node) ⇒ Object

Match node against the filter and return a [select, traverse] tuple of booleans



59
# File 'lib/modular_tree/filter.rb', line 59

def match(node) = @matcher.call(node)