Class: Jinx::Visitor::SyncVisitor

Inherits:
Jinx::Visitor show all
Defined in:
lib/jinx/helpers/visitor.rb

Instance Attribute Summary

Attributes inherited from Jinx::Visitor

#cycles, #lineage, #options, #visited

Instance Method Summary collapse

Methods inherited from Jinx::Visitor

#clear, #current, #cyclic_nodes, #depth_first?, #filter, #from, #node_children, #root, #sync, #visit_children, #visit_node_and_children, #visit_recursive, #visit_root, #visited?

Constructor Details

#initialize(visitor) {|nodes, others| ... } ⇒ SyncVisitor

Returns a new instance of SyncVisitor.

Parameters:

  • visitor (Visitor)

    the Visitor which will visit synchronized input

Yields:

  • (nodes, others)

    matches node in others (optional)



320
321
322
323
# File 'lib/jinx/helpers/visitor.rb', line 320

def initialize(visitor, &matcher)
  # the next node to visit is an array of child node pairs matched by the given matcher block
  super() { |nodes| match_children(visitor, nodes, &matcher) }
end

Instance Method Details

#match_children(visitor, nodes) {|nodes, others| ... } ⇒ Object (private)

Returns an array of arrays of matched children from the given parent nodes. The children are matched using the block given to this method, if supplied, or by index otherwise.

Yields:

  • (nodes, others)

    matches node in others (optional)

See Also:



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/jinx/helpers/visitor.rb', line 356

def match_children(visitor, nodes)
  # the parent nodes
  p1, p2 = nodes
  # this visitor's children
  c1 = visitor.node_children(p1)
  c2 = p2 ? visitor.node_children(p2) : []
  
  # Apply the matcher block on each of this visitor's children and the other children.
  # If no block is given, then group the children by index, which is the transpose of the array of
  # children arrays.
  if block_given? then
    # Match each item in the first children array to an item from the second children array using
    # then given block.
    matches = yield(c1, c2)
    c1.map { |c| [c, matches[c]] }
  else
    # Ensure that both children arrays are the same size.
    others = c2.size <= c1.size ? c2.fill(nil, c2.size...c1.size) : c2[0, c1.size]
    # The children grouped by index is the transpose of the array of children arrays.
    [c1, others].transpose
  end
end

#to_enum(*nodes) ⇒ Enumerable

Returns the result of applying the given block to each matched node starting at the given root nodes.

Parameters:

Returns:

  • (Enumerable)

    the result of applying the given block to each matched node starting at the given root nodes

Raises:

  • (ArgumentError)

    if the arguments do not consist of either two nodes or one two-item array



341
342
343
344
345
346
347
# File 'lib/jinx/helpers/visitor.rb', line 341

def to_enum(*nodes)
  if nodes.size == 1 then
    nodes = nodes.first
    raise ArgumentError.new("Sync visitor requires a pair of entry nodes") unless nodes.size == 2
  end
  super(nodes)
end

#visit(*nodes) ⇒ Object

Visits the given pair of nodes.

Parameters:

Raises:

  • (ArgumentError)

    if the arguments do not consist of either two nodes or one two-item array



329
330
331
332
333
334
335
# File 'lib/jinx/helpers/visitor.rb', line 329

def visit(*nodes)
  if nodes.size == 1 then
    nodes = nodes.first
    raise ArgumentError.new("Sync visitor requires a pair of entry nodes") unless nodes.size == 2
  end
  super(nodes)
end