Class: Piperator::Pipeline

Inherits:
Object
  • Object
show all
Defined in:
lib/piperator/pipeline.rb

Overview

Pipeline is responsible of composition of a lazy enumerable from callables. It contains a collection of pipes that respond to #call and return a enumerable.

For streaming purposes, it usually is desirable to have pipes that takes a lazy Enumerator as an argument a return a (modified) lazy Enumerator.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pipes = []) ⇒ Pipeline

Returns a new instance of Pipeline.



56
57
58
59
# File 'lib/piperator/pipeline.rb', line 56

def initialize(pipes = [])
  @pipes = pipes
  freeze
end

Class Method Details

.call(enumerable = []) ⇒ Enumerable

Returns enumerable given as an argument without modifications. Usable when Pipeline is used as an identity transformation.

Parameters:

  • enumerable (Enumerable) (defaults to: [])

Returns:

  • (Enumerable)


52
53
54
# File 'lib/piperator/pipeline.rb', line 52

def self.call(enumerable = [])
  enumerable
end

.lazy(&block) ⇒ Pipeline

Build a new pipeline from a lazily evaluated callable or an enumerable object.

callable.

Parameters:

  • block

    A block returning a callable(enumerable)

Returns:

  • (Pipeline)

    A pipeline containing only the lazily evaluated



15
16
17
18
19
20
21
# File 'lib/piperator/pipeline.rb', line 15

def self.lazy(&block)
  callable = nil
  Pipeline.new([lambda do |e|
    callable ||= block.call
    callable.call(e)
  end])
end

.pipe(callable) ⇒ Pipeline

Build a new pipeline from a callable or an enumerable object

Parameters:

  • callable

    An object responding to call(enumerable)

Returns:

  • (Pipeline)

    A pipeline containing only the callable



27
28
29
# File 'lib/piperator/pipeline.rb', line 27

def self.pipe(callable)
  Pipeline.new([callable])
end

.wrap(value) ⇒ Pipeline

Build a new pipeline from a from a non-callable, i.e. string, array, etc. This method will wrap the value in a proc, thus making it callable.

Piperator::Pipeline.wrap([1, 2, 3]).pipe(add_one)
# => [2, 3, 4]

# Wrap is syntactic sugar for wrapping a value in a proc
Piperator::Pipeline.pipe(->(_) { [1, 2, 3] }).pipe(add_one)
# => [2, 3, 4]

Parameters:

  • value

    A raw value which will be passed through the pipeline

Returns:

  • (Pipeline)

    A pipeline containing only the callable



43
44
45
# File 'lib/piperator/pipeline.rb', line 43

def self.wrap(value)
  Pipeline.new([->(_) { value }])
end

Instance Method Details

#call(enumerable = []) ⇒ Enumerable

Compute the pipeline and return a lazy enumerable with all the pipes.

Parameters:

  • enumerable (defaults to: [])

    Argument passed to the first pipe in the pipeline.

Returns:

  • (Enumerable)

    A lazy enumerable containing all the pipes



65
66
67
# File 'lib/piperator/pipeline.rb', line 65

def call(enumerable = [])
  @pipes.reduce(enumerable) { |pipe, memo| memo.call(pipe) }
end

#lazy(&block) ⇒ Pipeline

Add a new lazily evaluated part to the pipeline.

pipeline.

Parameters:

  • block

    A block returning a callable(enumerable) to append in

Returns:

  • (Pipeline)

    A new pipeline instance



81
82
83
84
85
86
87
# File 'lib/piperator/pipeline.rb', line 81

def lazy(&block)
  callable = nil
  Pipeline.new(@pipes + [lambda do |e|
    callable ||= block.call
    callable.call(e)
  end])
end

#pipe(other) ⇒ Pipeline

Add a new part to the pipeline

Parameters:

  • other

    A pipe to append in pipeline. Responds to #call.

Returns:

  • (Pipeline)

    A new pipeline instance



93
94
95
# File 'lib/piperator/pipeline.rb', line 93

def pipe(other)
  Pipeline.new(@pipes + [other])
end

#to_a(enumerable = []) ⇒ Array

Compute the pipeline and strictly evaluate the result

Returns:

  • (Array)


72
73
74
# File 'lib/piperator/pipeline.rb', line 72

def to_a(enumerable = [])
  call(enumerable).to_a
end

#wrap(other) ⇒ Pipeline

Add a new value to the pipeline

pipeline.

Parameters:

  • other

    A value which is wrapped into a pipe, then appended to the

Returns:

  • (Pipeline)

    A new pipeline instance



102
103
104
# File 'lib/piperator/pipeline.rb', line 102

def wrap(other)
  Pipeline.new(@pipes + [->(_) { other }])
end