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.
::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:
: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])
.
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
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]
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 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}
: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.
# File lib/aquarium/aspects/aspect.rb, line 138 def initialize *options, &block @first_option_that_was_method = [] opts = rationalize options init_specification opts, CANONICAL_OPTIONS, (Pointcut::ATTRIBUTE_OPTIONS_VALUES + KINDS_IN_PRIORITY_ORDER) do finish_specification_initialization &block end init_pointcuts validate_specification return if noop advise_join_points end
We have to ignore advice in the comparison. As recently discussed in ruby-users, there are very few situations. where Proc#eql? returns true.
# File lib/aquarium/aspects/aspect.rb, line 177 def eql? other self.object_id == other.object_id || (self.class.eql?(other.class) && specification == other.specification && pointcuts == other.pointcuts) end
# File lib/aquarium/aspects/aspect.rb, line 169 def inspect "Aspect: {specification: #{specification.inspect}, pointcuts: #{pointcuts.inspect}, advice: #{advice.inspect}}" end
# File lib/aquarium/aspects/aspect.rb, line 150 def join_points_matched get_jps :join_points_matched end
# File lib/aquarium/aspects/aspect.rb, line 154 def join_points_not_matched get_jps :join_points_not_matched end
# File lib/aquarium/aspects/aspect.rb, line 158 def unadvise return if noop @pointcuts.each do |pointcut| interesting_join_points(pointcut).each do |join_point| remove_advice_for_aspect_at join_point end end end