Class: Janeway::Interpreters::DescendantSegmentInterpreter
- Defined in:
- lib/janeway/interpreters/descendant_segment_interpreter.rb
Overview
Find all descendants of the current input that match the selector in the DescendantSegment
Constant Summary
Constants inherited from Base
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#interpret(input, parent, root, path) ⇒ Array<AST::Expression>
Find all descendants of the current input that match the selector in the DescendantSegment.
-
#visit(input, parent, path) ⇒ Object
Visit all descendants of
inputand concatenate the results ofblockat each node.
Methods inherited from Base
#as_json, #initialize, #selector, #to_s, #type
Constructor Details
This class inherits a constructor from Janeway::Interpreters::Base
Instance Method Details
#interpret(input, parent, root, path) ⇒ Array<AST::Expression>
Find all descendants of the current input that match the selector in the DescendantSegment
18 19 20 21 22 |
# File 'lib/janeway/interpreters/descendant_segment_interpreter.rb', line 18 def interpret(input, parent, root, path) visit(input, parent, path) do |node, parent_of_node, sub_path| @next.interpret(node, parent_of_node, root, sub_path) end end |
#visit(input, parent, path) ⇒ Object
Visit all descendants of input and concatenate the results of
block at each node. Iterative depth-first pre-order — a recursive
implementation would risk SystemStackError on deep JSON and allocated
an array-per-node plus a flatten pass.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/janeway/interpreters/descendant_segment_interpreter.rb', line 32 def visit(input, parent, path) results = [] stack = [[input, parent, path]] until stack.empty? node, node_parent, node_path = stack.pop results.concat(yield(node, node_parent, node_path)) case node when Array # Push in reverse so the leftmost child is popped first (pre-order). i = node.size - 1 while i >= 0 stack.push([node[i], node, node_path + [i]]) i -= 1 end when Hash # Iterate to an array once so we can walk it in reverse. pairs = node.to_a i = pairs.size - 1 while i >= 0 k, v = pairs[i] stack.push([v, node, node_path + [k]]) i -= 1 end end # Basic (non-container) types have no descendants — nothing to push. end results end |