Class Aquarium::Aspects::Aspect
In: lib/aquarium/aspects/aspect.rb
Parent: Object

Aspect

Aspect "advises" one or more method invocations for one or more types or objects (including class methods on types). The corresponding advice is a Proc that is invoked either before the join point, after it returns, after it raises an exception, after either event, or around the join point, meaning the advice runs and it decides when and if to invoke the advised method. (Hence, around advice can run code before and after the join point call and it can "veto" the actual join point call).

See also Aquarium::DSL for more information.

Methods

Included Modules

Advice ExclusionHandler DefaultObjectsHandler Aquarium::Aspects Aquarium::Utils::ArrayUtils Aquarium::Utils::HashUtils Aquarium::Utils::HtmlEscaper Aquarium::Utils::OptionsUtils

Constants

ASPECT_CANONICAL_OPTIONS = { "advice" => %w[action do_action use_advice advise_with invoke call], "pointcuts" => %w[pointcut], "named_pointcuts" => %w[named_pointcut], "exceptions" => %w[exception], "ignore_no_matching_join_points" => %[ignore_no_jps]
CANONICAL_OPTIONS = Pointcut::CANONICAL_OPTIONS.merge ASPECT_CANONICAL_OPTIONS

Attributes

advice  [R] 
pointcuts  [R] 
specification  [R] 

Public Class methods

Aspect.new (:around | :before | :after | :after_returning | :after_raising )

  (:pointcuts => [...]), :named_pointcuts => [...] |
   ((:types => [...] | :types_and_ancestors => [...] | :types_and_descendents => [...]
    | :types_and_nested_types | :objects => [...]),
    :methods => [], :method_options => [...],
    :attributes => [...], :attribute_options[...]),
   (:advice = advice | do |join_point, obj, *args| ...; end)

where the parameters often have many synonyms (mostly to support a "humane interface") and they are interpreted as followed:

Type of Advice

:around:Invoke the specified advice "around" the join points. It is up to the advice itself to call join_point.proceed (where join_point is the first option passed to the advice) if it wants the advised method to actually execute.
:before:Invoke the specified advice before the join point.
:after:Invoke the specified advice after the join point either returns successfully or raises an exception.
:after_returning:Invoke the specified advice after the join point returns successfully.
:after_raising [=> exception || [exception_list]]:Invoke the specified advice after the join point raises one of the specified exceptions. If no exceptions are specified, the advice is invoked after any exception is raised. An alternative syntax is :after_raising, :exception[s] => (exception || [exception_list]).

Advice

The advice to invoke before, after, or around the join points. Only one advice may be specified. If a block is specified, the following options are ignored.

  • :advice => proc
  • :action => proc
  • :do_action => proc
  • :use_advice => proc
  • :advise_with => proc
  • :invoke => proc
  • :call => proc

Pointcuts

A Pointcut, JoinPoint, or array of the same (Mixed is allowed.). Specifying pointcuts is mutually-exclusive with specifying them "indirectly" through :types, :objects, :methods, :attributes, :method_options, and :attribute_options parameters.

  • :pointcuts => pointcut || [pointcut_list]
  • :pointcut => pointcut || [pointcut_list]
  • :on_pointcut => pointcut || [pointcut_list]
  • :on_pointcuts => pointcut || [pointcut_list]
  • :in_pointcut => pointcut || [pointcut_list]
  • :in_pointcuts => pointcut || [pointcut_list]
  • :within_pointcut => pointcut || [pointcut_list]
  • :within_pointcuts => pointcut || [pointcut_list]

Named Pointcuts

Specify search criteria to locate Pointcuts defined as class constants and/or class variables. The options for the named_pointcuts parameter must form a hash and satisfy the requirements documented for Aquarium::Finders::PointcutFinder#find. Specifying named pointcuts is also mutually-exclusive with specifying Pointcuts "indirectly" through :types, :objects, :methods, :attributes, :method_options, and :attribute_options parameters.

  • :named_pointcuts => {PointcutFinder options}
  • :named_pointcut => {PointcutFinder options}
  • :on_named_pointcuts => {PointcutFinder options}
  • :on_named_pointcut => {PointcutFinder options}
  • :in_named_pointcuts => {PointcutFinder options}
  • :in_named_pointcut => {PointcutFinder options}
  • :within_named_pointcuts => {PointcutFinder options}
  • :within_named_pointcut => {PointcutFinder options}

Exclude Pointcuts

Exclude the specified pointcuts. The exclude_ prefix can be used with any of the :pointcuts and :named_pointcuts synonyms.

  • :exclude_pointcuts => pointcut || [pointcut_list]
  • :exclude_named_pointcuts => {PointcutFinder options}

Miscellaneous Options

:ignore_no_matching_join_points => true | false:Do not issue a warning if no join points are actually matched by the aspect. By default, the value is false, meaning that a WARN-level message will be written to the log. It is usually very helpful to be warned when no matches occurred, for debugging purposes! A synonym for this option is ignore_no_jps => true | false.

For other options e.g., :types, :methods, Aspect#new accepts all the options that Pointcut#new accepts. It also accepts the "universal" options documented in Aquarium::Utils::OptionsUtils.

[Source]

     # File lib/aquarium/aspects/aspect.rb, line 138
138:       def initialize *options, &block
139:         @first_option_that_was_method = []
140:         opts = rationalize options
141:         init_specification opts, CANONICAL_OPTIONS, (Pointcut::ATTRIBUTE_OPTIONS_VALUES + KINDS_IN_PRIORITY_ORDER) do
142:           finish_specification_initialization &block
143:         end
144:         init_pointcuts
145:         validate_specification
146:         return if noop
147:         advise_join_points
148:       end

Public Instance methods

==(other)

Alias for eql?

We have to ignore advice in the comparison. As recently discussed in ruby-users, there are very few situations. where Proc#eql? returns true.

[Source]

     # File lib/aquarium/aspects/aspect.rb, line 177
177:       def eql? other
178:         self.object_id == other.object_id ||
179:           (self.class.eql?(other.class) && specification == other.specification && pointcuts == other.pointcuts)
180:       end

[Source]

     # File lib/aquarium/aspects/aspect.rb, line 169
169:       def inspect
170:         "Aspect: {specification: #{specification.inspect}, pointcuts: #{pointcuts.inspect}, advice: #{advice.inspect}}"
171:       end

[Source]

     # File lib/aquarium/aspects/aspect.rb, line 150
150:       def join_points_matched 
151:         get_jps :join_points_matched
152:       end

[Source]

     # File lib/aquarium/aspects/aspect.rb, line 154
154:       def join_points_not_matched
155:         get_jps :join_points_not_matched
156:       end
to_s()

Alias for inspect

[Source]

     # File lib/aquarium/aspects/aspect.rb, line 158
158:       def unadvise
159:         return if noop
160:         @pointcuts.each do |pointcut|
161:           interesting_join_points(pointcut).each do |join_point|
162:             remove_advice_for_aspect_at join_point
163:           end
164:         end
165:       end
unadvise_join_points()

Alias for unadvise

[Validate]