class Mementus::Pipeline::Step
Represents a step in a pipeline chain.
New steps are constructed from a `source` enumerable (usually the previous step in the chain) and an optional `pipe` which provides the strategy for generating output values.
Each step has an internal `Fiber` context which is used to yield control to the next step in the chain on each value in the iteration, rather than cycle through the entire list of values before forwarding control.
This avoids the problem of iterating over a huge set of nodes and edges which are then discarded by a later step.
The approach here is roughly similar to the way that Ruby chains together `Enumerator::Lazy` objects.
Attributes
Public Class Methods
Initialize a pipeline step from the given source.
@param source [#each] @param pipe [Mementus::Pipeline::Pipe]
# File lib/mementus/pipeline/step.rb, line 23 def initialize(source, pipe=nil, graph=nil) @source = source @pipe = pipe || Pipe.new(graph) @graph = graph end
Public Instance Methods
Returns all values in the sequence
# File lib/mementus/pipeline/step.rb, line 102 def all to_enum.to_a end
# File lib/mementus/pipeline/step.rb, line 115 def breadth_first(method=:out) Step.new(BreadthFirstSearch.new(graph, source.first.id, method)) end
# File lib/mementus/pipeline/step.rb, line 111 def depth_first(method=:out) Step.new(DepthFirstSearch.new(graph, source.first.id, method)) end
Loop through each value in the sequence, yielding control to the next step if necessary.
If a block is provided, it is called with the value. Otherwise, a lazy enumerator representing the wrapped source is returned.
# File lib/mementus/pipeline/step.rb, line 37 def each return to_enum unless block_given? context = Fiber.new do source.each do |element| pipe.call(element) end raise StopIteration end loop do yield context.resume end end
Returns the first value in the sequence.
# File lib/mementus/pipeline/step.rb, line 97 def first to_enum.first end
Dereference ids from the source elements.
# File lib/mementus/pipeline/step.rb, line 54 def id ids = to_enum.map { |element| element.id } return ids.first if ids.length == 1 ids end
Traverse to the incoming nodes pointing to the source elements.
# File lib/mementus/pipeline/step.rb, line 70 def in(match=nil) incoming_nodes = source.inject([]) do |result, node| result.concat(node.incoming(match)) end Step.new(incoming_nodes, Pipe.new(graph), graph) end
Traverse to the incoming edges pointing to the source elements.
# File lib/mementus/pipeline/step.rb, line 88 def in_e(match=nil) incoming_edges = source.inject([]) do |result, node| result.concat(graph.incoming_edges(node.id, match)) end Step.new(incoming_edges, Pipe.new(graph), graph) end
Traverse to the outgoing nodes adjacent to the source elements.
# File lib/mementus/pipeline/step.rb, line 61 def out(match=nil) outgoing_nodes = source.inject([]) do |result, node| result.concat(node.outgoing(match)) end Step.new(outgoing_nodes, Pipe.new(graph), graph) end
Traverse to the outgoing edges from the source elements.
# File lib/mementus/pipeline/step.rb, line 79 def out_e(match=nil) outgoing_edges = source.inject([]) do |result, node| result.concat(graph.outgoing_edges(node.id, match)) end Step.new(outgoing_edges, Pipe.new(graph), graph) end
Returns the given number of values from the sequence.
# File lib/mementus/pipeline/step.rb, line 107 def take(num) to_enum.take(num) end