Class: Needle::Pipeline::Collection

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

Overview

Represents a collection of pipeline elements. Elements may be added to the pipeline, and then returned as a single object representing the chain of pipeline elements.

Defined Under Namespace

Classes: BlockElement

Instance Method Summary collapse

Constructor Details

#initialize(service_point) ⇒ Collection

Create a new pipeline element collection, initially empty.



49
50
51
52
# File 'lib/needle/pipeline/collection.rb', line 49

def initialize( service_point )
  @elements = []
  @service_point = service_point
end

Instance Method Details

#add(*args, &block) ⇒ Object

Add a new pipeline element to this collection. If the first parameter is a symbol or a string, it is taken to be the name of the element to add. If no explicit implementation is given, then the implementation is looked up in the :pipeline_elements service, using the given name.

After the first parameter, if the next parameter is numeric, it is taken to mean the priority of the element. This overrides whatever default priority is given for the selected element.

If the next parameter responds to the :new message, it is taken to be an explicit implementation of the element. This is only valid if a block is not given. If a block is given, then it is always taken to be the implementation of the element.

If the last parameter is a Hash, it is taken to be a map of options that should be passed to the element when it is instantiated.

This returns self, so that #add calls may be chained.

Raises:

  • (ArgumentError)


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/needle/pipeline/collection.rb', line 73

def add( *args, &block )
  name = priority = nil
  options = {}
  klass = nil
  element = nil

  if [ Symbol, String ].any? { |i| args.first.is_a?( i ) }
    name = args.shift.to_s.intern
  end
  priority = args.shift if args.first.is_a?( Numeric )
  klass = args.shift if args.first.respond_to?( :new ) && block.nil?
  options = args.shift if args.first.is_a?( Hash )

  raise ArgumentError,
    "bad argument list #{args.inspect}" unless args.empty?

  if block
    element = BlockElement.new( @service_point, name, priority,
      options, block )
  else
    klass ||= @service_point.container[:pipeline_elements].fetch( name )
    element = klass.new( @service_point, name, priority, options )
  end

  @elements << element
  self
end

#chain_to(block) ⇒ Object

Builds a linked list of the elements, with the last element being the block (or block-like) object given by the parameter. Higher-priority elements will be closer to the head of the list.



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/needle/pipeline/collection.rb', line 120

def chain_to( block )
  head = tail = nil
  @elements.sort.reverse.each do |el|
    if head
      tail.succ = el
      tail = el
    else # first time through...
      head = tail = el
    end
  end

  if tail
    tail.succ = block
    return head
  else
    return block
  end
end

#get(name) ⇒ Object

Returns the first pipeline element with the given name, or nil if no such element exists.



103
104
105
106
# File 'lib/needle/pipeline/collection.rb', line 103

def get( name )
  name = name.to_s.intern
  @elements.find { |el| name == el.name }
end

#reset!(*args) ⇒ Object

Clears the state for each named element. If no elements are named, all elements are cleared.



110
111
112
113
114
115
# File 'lib/needle/pipeline/collection.rb', line 110

def reset!( *args )
  @elements.each do |element|
    element.reset! if args.empty? || args.include?( element.name )
  end
  self
end