Class: Jinx::Visitor::SyncVisitor

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

Instance Attribute Summary

Attributes inherited from Jinx::Visitor

#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)



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

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:



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

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



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

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



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

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