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, #depth_first?, #filter, #from, #node_children, #prune_cycle_nodes, #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)



310
311
312
313
# File 'lib/jinx/helpers/visitor.rb', line 310

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:



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/jinx/helpers/visitor.rb', line 346

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) ⇒ Object

Returns an Enumerable which applies the given block to each matched node starting at the given nodes.

Raises ArgumentError if nodes does not consist of either two node arguments or one two-item Array argument.



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

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.

Raises ArgumentError if nodes does not consist of either two node arguments or one two-item Array argument.



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

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