Class: Needle::Interceptor

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

Overview

This represents the definition of an interceptor as it is attached to a service point. Instances of Interceptor are also used for configuring themselves programmatically.

You will almost never instantiate an Interceptor object directly. Instead, use the Container#intercept method. You can then configure the new interceptor by chaining methods of the new object together, quite readably:

container.intercept( :foo ).with! { some_interceptor }.
  with_options( :arg => :value )

You can also create new interceptors on the fly via the Interceptor#doing method.

Defined Under Namespace

Classes: DynamicInterceptor

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeInterceptor

Create a new Interceptor definition. By default, it has no implementation and a priority of 0.


81
82
83
84
# File 'lib/needle/interceptor.rb', line 81

def initialize
  @options = { :priority => 0 }
  @doing = @with = nil
end

Instance Attribute Details

#optionsObject (readonly)

The set of options that were given to this interceptor via the #with_options method.


77
78
79
# File 'lib/needle/interceptor.rb', line 77

def options
  @options
end

Instance Method Details

#[](name) ⇒ Object

A convenience method for querying the options on an interceptor definition.


177
178
179
# File 'lib/needle/interceptor.rb', line 177

def []( name )
  @options[ name ]
end

#[]=(name, value) ⇒ Object

A convenience method for setting the options on an interceptor definition.


183
184
185
# File 'lib/needle/interceptor.rb', line 183

def []=( name, value )
  @options[ name ] = value
end

#actionObject

Returns the action that was specified for this interceptor as a proc instance. This will either be the block passed to #with, or a proc that wraps the instantiation of a DynamicInterceptor (when #doing was used).

If neither #with nor #doing were specified, an InterceptorConfigurationError is raised.


93
94
95
96
97
98
99
# File 'lib/needle/interceptor.rb', line 93

def action
  return @with if @with
  raise InterceptorConfigurationError,
    "You must specify either 'with' or 'doing'" unless @doing

  return proc { |c| DynamicInterceptor.new( @doing ) }
end

#doing(&block) ⇒ Object

This allows new interceptors to be defined “on-the-fly”. The associated block must accept two parameters–an object representing the chain of interceptors, and the context of the current method invocation. The block should then invoke #process_next on the chain (passing the context as the lone parameter) when the next element of the chain should be invoked.

You should only call #doing once per interceptor, and never after invoking #with on the same interceptor.


149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/needle/interceptor.rb', line 149

def doing( &block )
  if @doing
    raise InterceptorConfigurationError,
      "you cannot redefine 'doing' behavior"
  end

  if @with
    raise InterceptorConfigurationError,
      "cannot specify 'doing' after specifying 'with'"
  end

  if block.nil?
    raise InterceptorConfigurationError,
      "you must specify a block to 'doing'"
  end

  @doing = block
  self
end

#with(&block) ⇒ Object

Sets the action for this interceptor to be that defined by the interceptor returned when the block is executed. You can only invoke #with once, and never after previously invoking #doing on the same interceptor instance.

Usage:

container.intercept( :foo ).
  with { |c| c.logging_interceptor }

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/needle/interceptor.rb', line 110

def with( &block )
  if @with
    raise InterceptorConfigurationError,
      "you cannot redefine 'with' behavior"
  end

  if @doing
    raise InterceptorConfigurationError,
      "cannot specify 'with' after specifying 'doing'"
  end

  if block.nil?
    raise InterceptorConfigurationError,
      "you must specify a block to 'with'"
  end

  @with = block
  self
end

#with!(&block) ⇒ Object

This is identical to #with, but it wraps the block in another proc that calls instance_eval on the container, with the block.

Usage:

container.intercept( :foo ).
  with! { logging_interceptor }

137
138
139
# File 'lib/needle/interceptor.rb', line 137

def with!( &block )
  with { |c| c.instance_eval( &block ) }
end

#with_options(opts = {}) ⇒ Object

Merge the given opts hash into the interceptors options hash.


170
171
172
173
# File 'lib/needle/interceptor.rb', line 170

def with_options( opts={} )
  @options.update opts
  self
end