Class: Aquarium::Aspects::Aspect
- Includes:
- Aquarium::Aspects, Advice, DefaultObjectsHandler, ExclusionHandler, Utils::ArrayUtils, Utils::HashUtils, Utils::HtmlEscaper, Utils::OptionsUtils
- Defined in:
- lib/aquarium/aspects/aspect.rb
Overview
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.
Constant Summary collapse
- 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" => %w[ignore_no_jps] }
- CANONICAL_OPTIONS =
Pointcut::CANONICAL_OPTIONS.merge ASPECT_CANONICAL_OPTIONS
Constants included from Advice
Aquarium::Aspects::Advice::KINDS_IN_PRIORITY_ORDER, Aquarium::Aspects::Advice::UNKNOWN_ADVICE_KIND
Instance Attribute Summary collapse
-
#advice ⇒ Object
readonly
Returns the value of attribute advice.
-
#pointcuts ⇒ Object
readonly
Returns the value of attribute pointcuts.
-
#specification ⇒ Object
readonly
Returns the value of attribute specification.
Instance Method Summary collapse
-
#eql?(other) ⇒ Boolean
(also: #==)
We have to ignore advice in the comparison.
-
#initialize(*options, &block) ⇒ Aspect
constructor
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).
- #inspect ⇒ Object (also: #to_s)
- #join_points_matched ⇒ Object
- #join_points_not_matched ⇒ Object
- #unadvise ⇒ Object (also: #unadvise_join_points)
Methods included from Utils::OptionsUtils
append_features, #hashify, #init_specification, universal_options, universal_prepositions, #validate_options
Methods included from Utils::ArrayUtils
#make_array, make_array, #strip_array_nils, strip_array_nils
Methods included from Utils::SetUtils
#make_set, #strip_set_nils, strip_set_nils
Methods included from Utils::HtmlEscaper
Methods included from Utils::HashUtils
Methods included from DefaultObjectsHandler
#default_objects_given, #default_objects_given?, #use_default_objects_if_defined
Methods included from ExclusionHandler
#all_excluded_pointcuts, #is_excluded_join_point?, #is_excluded_method?, #is_excluded_pointcut?, #is_excluded_type_or_object?, #is_explicitly_excluded_method?, #join_point_excluded?, #matches_excluded_method_regex?, #set_calculated_excluded_pointcuts
Methods included from Advice
compare_advice_kinds, debug_backtraces, debug_backtraces=, kinds, sort_by_priority_order
Constructor Details
#initialize(*options, &block) ⇒ Aspect
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
(wherejoin_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.
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/aquarium/aspects/aspect.rb', line 138 def initialize *, &block @first_option_that_was_method = [] opts = rationalize 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 |
Instance Attribute Details
#advice ⇒ Object (readonly)
Returns the value of attribute advice.
33 34 35 |
# File 'lib/aquarium/aspects/aspect.rb', line 33 def advice @advice end |
#pointcuts ⇒ Object (readonly)
Returns the value of attribute pointcuts.
33 34 35 |
# File 'lib/aquarium/aspects/aspect.rb', line 33 def pointcuts @pointcuts end |
#specification ⇒ Object (readonly)
Returns the value of attribute specification.
33 34 35 |
# File 'lib/aquarium/aspects/aspect.rb', line 33 def specification @specification end |
Instance Method Details
#eql?(other) ⇒ Boolean Also known as: ==
We have to ignore advice in the comparison. As recently discussed in ruby-users, there are very few situations. where Proc#eql? returns true.
177 178 179 180 |
# 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 |
#inspect ⇒ Object Also known as: to_s
169 170 171 |
# File 'lib/aquarium/aspects/aspect.rb', line 169 def inspect "Aspect: {specification: #{specification.inspect}, pointcuts: #{pointcuts.inspect}, advice: #{advice.inspect}}" end |
#join_points_matched ⇒ Object
150 151 152 |
# File 'lib/aquarium/aspects/aspect.rb', line 150 def join_points_matched get_jps :join_points_matched end |
#join_points_not_matched ⇒ Object
154 155 156 |
# File 'lib/aquarium/aspects/aspect.rb', line 154 def join_points_not_matched get_jps :join_points_not_matched end |
#unadvise ⇒ Object Also known as: unadvise_join_points
158 159 160 161 162 163 164 165 |
# 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 |