Class: Plumb::Pipeline

Inherits:
Object
  • Object
show all
Includes:
Composable
Defined in:
lib/plumb/pipeline.rb

Defined Under Namespace

Classes: AroundStep

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Composable

#&, #/, #>>, #[], #absorb_input, #absorb_output, #accepted_type, #as_node, #build, #check, #defer, #fusable_step?, #fuse_with, #generate, #idempotent?, included, #invalid, #invoke, #match, #metadata, #not, #pipeline, #policy, resolve_operand, #static, #to_json_schema, #to_mermaid, #to_plumb_type, #to_s, #transform, #value, #where, #with, wrap, #|

Methods included from Callable

#parse, #resolve

Constructor Details

#initialize(type: Types::Any, freeze_after: true, &setup) ⇒ Pipeline

Returns a new instance of Pipeline.



45
46
47
48
49
50
51
# File 'lib/plumb/pipeline.rb', line 45

def initialize(type: Types::Any, freeze_after: true, &setup)
  self.type = type
  @around_blocks = self.class.around_blocks.dup

  configure(&setup) if block_given?
  freeze if freeze_after
end

Instance Attribute Details

#childrenObject (readonly)

Returns the value of attribute children.



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

def children
  @children
end

Class Method Details

.around(callable = nil, &block) ⇒ Object



32
33
34
35
# File 'lib/plumb/pipeline.rb', line 32

def around(callable = nil, &block)
  around_blocks << (callable || block)
  self
end

.around_blocksObject



28
29
30
# File 'lib/plumb/pipeline.rb', line 28

def around_blocks
  @around_blocks ||= []
end

.inherited(subclass) ⇒ Object



37
38
39
40
# File 'lib/plumb/pipeline.rb', line 37

def inherited(subclass)
  around_blocks.each { |block| subclass.around(block) }
  super
end

Instance Method Details

#around(callable = nil, &block) ⇒ Object



104
105
106
107
# File 'lib/plumb/pipeline.rb', line 104

def around(callable = nil, &block)
  @around_blocks << (callable || block)
  self
end

#call(result) ⇒ Object



53
54
55
# File 'lib/plumb/pipeline.rb', line 53

def call(result)
  @type.call(result)
end

#input_typeObject

A Pipeline is a transparent wrapper around its accumulated composition, so it delegates its type-flow to that inner type. When the inner steps are opaque (plain procs/around-wrapped steps) those resolve to Any and the Pipeline still opts out of #>> composition type-checks; when they carry real types, the Pipeline participates accurately.



62
# File 'lib/plumb/pipeline.rb', line 62

def input_type = @type.input_type

#output_typeObject



63
# File 'lib/plumb/pipeline.rb', line 63

def output_type = @type.output_type

#step(callable = nil, &block) ⇒ Object

Add a step. A pipeline is a sequence of validators/coercions that progressively narrows its data, so steps are non-strict by default: #step chains with #/, skipping the composition type-check (a later step may legitimately narrow what an earlier one produced). Use #step! when you want the strict #>> check — a build-time error if a step could never accept the previous step's output.

pl.step(type_or_callable)        # non-strict chain (via #/)
pl.step!(type_or_callable)       # strict #>> chain (type-checked)
pl.step(output_type) { |r| ... } # a Function: validates the current
                               # output, runs the block, and declares
                               # `output_type` as the produced type


86
87
88
# File 'lib/plumb/pipeline.rb', line 86

def step(callable = nil, &block)
  add_step(callable, strict: false, &block)
end

#step!(callable = nil, &block) ⇒ Object

Strict counterpart of #step: chains with #>>, so it raises Plumb::TypeError at build time if the step can't accept what the pipeline currently produces. See #step.

NOTE the output_type + block form cannot fail this check: the step's input type is DERIVED from what the pipeline already produces (see #add_step), so the two match by construction and #step! behaves as #step there. That is not a gap — pl.step!(::Integer) { … } after a String pipeline is legitimate, because the block is what does the converting; only the value it RETURNS is checked, against the declared output type.



100
101
102
# File 'lib/plumb/pipeline.rb', line 100

def step!(callable = nil, &block)
  add_step(callable, strict: true, &block)
end

#subtype_identityComposable

Use the accumulated composition as this pipeline's subtype identity. Merely delegating input/output flow would let composition checks work while leaving the Pipeline unrelated to the same type inside containers.

Returns:



69
# File 'lib/plumb/pipeline.rb', line 69

def subtype_identity = @type

#value_preserving?Boolean

Returns whether the accumulated composition preserves values.

Returns:

  • (Boolean)

    whether the accumulated composition preserves values



72
# File 'lib/plumb/pipeline.rb', line 72

def value_preserving? = @type.value_preserving?