class Retl::Path
A Path
is a blueprint for transforming data
A Path
is a sequence of steps that are executed on data in order to transform it.
Paths can be built with a block using the API defined in the {#PathBuilder}.
Steps are added to the Path
with the {#add_step} method.
A Path
can act on a single piece of data with the {#call} method.
A Path
can transform a list of data with the {#transform} method.
@example
path = Retl::Path.new do step do |data| data[:something] = "some value" data end calculate(:something_else) do "some other value" end transform do |data| data[:something_together] = data[:something] + data[:something_else] end end path.transform(data)
Attributes
Public Class Methods
Initializes a new Path
@param parent [Path] - a Path
to inherit from
# File lib/retl/path.rb, line 48 def initialize(parent=nil, &block) @steps = [] @dependencies = {} @forks = {} @fork_builders = {} if parent @dependencies = parent.dependencies.dup add_step parent.dup, handler: ExplodeHandler end build(&block) if block end
Public Instance Methods
Adds a depdency to the Path
@param name [Symbol] the name of the dependency
(should be a valid Ruby method)
@param source [#call] a callable object that will return the depdency
@return [void]
# File lib/retl/path.rb, line 176 def add_dependency(name, source) @dependencies[name] = source end
Adds an fork to the Path
Forks can be accessed via forks
@example
path.add_fork(:river) do filter { |data| data[:is_wet] } end path.forks(:river)
@param name [Symbol] the name of the fork
@return [void]
# File lib/retl/path.rb, line 140 def add_fork(name, &block) fork = Path.new(&block) @dependencies.each do |name, dependency| fork.add_dependency name, dependency end add_handler ForkHandler.new(name) @forks[name] = fork end
Adds a fork builder block
@param name [Symbol] the name of the fork to build @param &block [Block] the block that builds the fork
@return [Fork] the built fork
# File lib/retl/path.rb, line 164 def add_fork_builder(name, &block) @fork_builders[name] = block add_fork(name, &block) end
# File lib/retl/path.rb, line 94 def add_handler(handler) @steps << handler end
Adds a step to the Path
A step is called with data and is expected to return complete, modified data.
Steps are executed in the sequence they are added.
@param step [#call(data)] the step to take
@return [void]
# File lib/retl/path.rb, line 90 def add_step(step, handler: StepHandler) add_handler handler.new(step) end
Builds a Path
with the PathBuilder
DSL
@return [void]
# File lib/retl/path.rb, line 65 def build(&block) PathBuilder.new(self, &block) end
Execuutes the Path
with the given data
Currently the DSL mostly supports Hash based data, so this expects a Hash.
Since a piece of data can now be exploded, this method will always return an Array.
@param data [Hash] the data that will be transformed by the Path
@param context [Context] the execution context for the transformation
@return [Array<Hash>] the transformed data
# File lib/retl/path.rb, line 110 def call(input, context=Context.new(self)) @steps.reduce([input]) do |queue, handler| queue.each do |data| begin handler.push_in(data, context) rescue Exception => e raise StepExecutionError.new( input_data: input, current_data: data, step: handler ) end end handler.output end end
Gets a fork by name
@param name [Symbol] the name of the fork to get
@return [Path] the forked path
# File lib/retl/path.rb, line 154 def forks(name) @forks[name] end
Initializer when copying a Path
When a Path
is copied, a copy of the Path’s steps need to be copied as well. That was if additional steps are added to the original Path
they won’t be part of the copied Path
.
# File lib/retl/path.rb, line 74 def initialize_copy(source) @steps = source.steps.dup @forks = {} @fork_builders = {} end
Executes the Path
with data
@param [Enumerable] the data that will be processed by the Path
@option options that will be passed to depends_on for the context
@return [Transformation] the Tranformation of the data by the Path
# File lib/retl/path.rb, line 186 def transform(enumerable, options={}) Transformation.new(enumerable, self, options) end
# File lib/retl/path.rb, line 190 def transform!(enumerable, options={}) transform(enumerable, options).tap do |transformation| transformation.execution_strategy = ThreadedExecution end end