class Aquarium::Aspects::Pointcut

Pointcut

Pointcuts are queries on JoinPoints combined with binding of context data to that will be useful during advice execution. The Pointcut locates the join points that match the input criteria, remembering the found join points as well as the the criteria that yielded no matches (mostly useful for debugging Pointcut definitions)

Pointcut (composition)

Since Pointcuts are queries, they can be composed, i.e., unions and intersections of them can be computed, yielding new Pointcuts.

Constants

ATTRIBUTE_OPTIONS_VALUES
CANONICAL_OPTIONS
POINTCUT_CANONICAL_OPTIONS

Attributes

candidate_join_points[RW]
candidate_objects[RW]
candidate_types[RW]
candidate_types_excluded[RW]
join_points_matched[RW]
join_points_not_matched[RW]
specification[RW]

Public Class Methods

make_attribute_reading_writing_options(options_hash) click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
250 def self.make_attribute_reading_writing_options options_hash
251   result = {}
252   [:writing, :changing, :reading].each do |attr_key|
253     next if options_hash[attr_key].nil? or options_hash[attr_key].to_s.empty?
254     result[:attributes] ||= Set.new([])
255     result[:attribute_options] ||= Set.new([])
256     result[:attributes].merge(Aquarium::Utils::ArrayUtils.make_array(options_hash[attr_key]))
257     attr_opt = attr_key == :reading ? :readers : :writers
258     result[:attribute_options] << attr_opt
259   end
260   result
261 end
new(options = {}) click to toggle source

Construct a Pointcut for methods in types or objects.

Pointcut.new :join_points => [...] | :type{s} => [...] | :object{s} => [...]
   {, :method{s} => [], :method_options => [...],
   :attribute{s} => [...], :attribute_options[...]}

where the “{}” indicate optional elements. Most of the arguments have many synonyms, shown below, to promote an English-like DSL.

The options include the following.

Join Points

Specify one or an array of join_points.

  • :join_points => join_point || [join_point_list]

  • :join_point => join_point || [join_point_list]

  • :for_join_points => join_point || [join_point_list]

  • :for_join_point => join_point || [join_point_list]

  • :on_join_points => join_point || [join_point_list]

  • :on_join_point => join_point || [join_point_list]

  • :within_join_points => join_point || [join_point_list]

  • :within_join_point => join_point || [join_point_list]

Types

Specify a type, type name, type name regular expression or an array of the same. (Mixed is allowed.)

  • :types => type || [type_list]

  • :type => type || [type_list]

  • :for_types => type || [type_list]

  • :for_type => type || [type_list]

  • :on_types => type || [type_list]

  • :on_type => type || [type_list]

  • :within_types => type || [type_list]

  • :within_type => type || [type_list]

Types and Ancestors or Descendents

Specify a type, type name, type name regular expression or an array of the same. (Mixed is allowed.) The ancestors or descendents will also be found. To find both ancestors and descendents, use both options.

  • :types_and_descendents => type || [type_list]

  • :type_and_descendents => type || [type_list]

  • :types_and_ancestors => type || [type_list]

  • :type_and_ancestors => type || [type_list]

  • :for_types_and_ancestors => type || [type_list]

  • :for_type_and_ancestors => type || [type_list]

  • :on_types_and_descendents => type || [type_list]

  • :on_type_and_descendents => type || [type_list]

  • :on_types_and_ancestors => type || [type_list]

  • :on_type_and_ancestors => type || [type_list]

  • :within_types_and_descendents => type || [type_list]

  • :within_type_and_descendents => type || [type_list]

  • :within_types_and_ancestors => type || [type_list]

  • :within_type_and_ancestors => type || [type_list]

Types and Nested Types

Specify a type, type name, type name regular expression or an array of the same. (Mixed is allowed.) The nested (enclosed) types will also be found.

  • :types_and_nested_types => type || [type_list]

  • :type_and_nested_types => type || [type_list]

  • :types_and_nested => type || [type_list]

  • :type_and_nested => type || [type_list]

  • :for_types_and_nested_types => type || [type_list]

  • :for_type_and_nested_types => type || [type_list]

  • :for_types_and_nested => type || [type_list]

  • :for_type_and_nested => type || [type_list]

  • :on_types_and_nested_types => type || [type_list]

  • :on_type_and_nested_types => type || [type_list]

  • :on_types_and_nested => type || [type_list]

  • :on_type_and_nested => type || [type_list]

  • :within_types_and_nested_types => type || [type_list]

  • :within_type_and_nested_types => type || [type_list]

  • :within_types_and_nested => type || [type_list]

  • :within_type_and_nested => type || [type_list]

Objects
  • :objects => object || [object_list]

  • :object => object || [object_list]

  • :for_objects => object || [object_list]

  • :for_object => object || [object_list]

  • :on_objects => object || [object_list]

  • :on_object => object || [object_list]

  • :within_objects => object || [object_list]

  • :within_object => object || [object_list]

“Default” Objects

An “internal” flag used by Aspect::DSL#pointcut. When no object or type is specified explicitly, the value of :default_objects will be used, if defined. Aspect::DSL#pointcut sets the value to self, so the user doesn't have to specify a type or object in the contexts where that would be useful, e.g., pointcuts defined within a type for join points within itself. WARNING: This flag is subject to change, so don't use it explicitly!

  • :default_objects => object || [object_list]

  • :default_object => object || [object_list]

Methods

A method name, name regular expession or an array of the same. By default, if neither :methods nor :attributes are specified, all public instance methods will be found, with the method option :exclude_ancestor_methods implied, unless explicit method options are given.

  • :methods => method || [method_list]

  • :method => method || [method_list]

  • :within_methods => method || [method_list]

  • :within_method => method || [method_list]

  • :calling => method || [method_list]

  • :calls_to => method || [method_list]

  • :invoking => method || [method_list]

  • :invocations_of => method || [method_list]

  • :sending_message_to => method || [method_list]

Method Options

One or more options supported by Aquarium::Finders::MethodFinder. The :exclude_ancestor_methods option is most useful.

  • :method_options => [options]

Attributes

An attribute name, regular expession or array of the same. WARNING This is syntactic sugar for the corresponding attribute readers and/or writers methods. The actual attribute accesses are not advised, which can lead to unexpected behavior. A goal before V1.0 is to support actual attribute accesses, if possible.

  • :attributes => attribute || [attribute_list]

  • :attribute => attribute || [attribute_list]

  • :reading => attribute || [attribute_list]

  • :writing => attribute || [attribute_list]

  • :changing => attribute || [attribute_list]

  • :accessing => attribute || [attribute_list]

If :reading is specified, just attribute readers are matched. If :writing is specified, just attribute writers are matched. If :accessing is specified, both readers and writers are matched. Any matches will be joined with the matched :methods..

Attribute Options

One or more of :readers, :reader (synonymous), :writers, and/or :writer (synonymous). By default, both readers and writers are matched. :reading => ... is synonymous with :attributes => ..., :attribute_options => [:readers]. :writing => ... and :changing => ... are synonymous with :attributes => ..., :attribute_options => [:writers]. :accessing => ... is synonymous with :attributes => ....

  • :attribute_options => [options]

Exclusion Options

Exclude the specified “things” from the matched join points. If pointcuts are excluded, they should be subsets of the matched pointcuts. Otherwise, the resulting pointcut will be empty!

  • :exclude_pointcuts => pc || [pc_list]

  • :exclude_pointcut => pc || [pc_list]

  • :exclude_join_points => jp || [jp_list]

  • :exclude_join_point => jp || [jp_list]

  • :exclude_types => type || [type_list]

  • :exclude_types => type || [type_list]

  • :exclude_type => type || [type_list]

  • :exclude_types_and_descendents => type || [type_list]

  • :exclude_type_and_descendents => type || [type_list]

  • :exclude_types_and_ancestors => type || [type_list]

  • :exclude_type_and_ancestors => type || [type_list]

  • :exclude_types_and_nested_types => type || [type_list]

  • :exclude_type_and_nested_types => type || [type_list]

  • :exclude_types_and_nested => type || [type_list]

  • :exclude_type_and_nested => type || [type_list]

  • :exclude_objects => object || [object_list]

  • :exclude_object => object || [object_list]

  • :exclude_methods => method || [method_list]

  • :exclude_method => method || [method_list]

  • :exclude_attributes => attribute || [attribute_list]

  • :exclude_attribute => attribute || [attribute_list]

The exclude_ prefix works with the synonyms of the options shown.

Pointcut.new also accepts all the “universal” options documented in Aquarium::Utils::OptionsUtils.

    # File lib/aquarium/aspects/pointcut.rb
191 def initialize options = {} 
192   init_specification options, CANONICAL_OPTIONS, (ATTRIBUTE_OPTIONS_VALUES + Advice::KINDS_IN_PRIORITY_ORDER) do 
193     finish_specification_initialization
194   end
195   return if noop
196   init_candidate_types 
197   init_candidate_objects
198   init_candidate_join_points
199   init_join_points
200 end
validate_attribute_options(spec_hash, options_hash) click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
280 def self.validate_attribute_options spec_hash, options_hash
281   raise Aquarium::Utils::InvalidOptions.new(":all is not yet supported for :attributes.") if spec_hash[:attributes] == Set.new([:all])
282   if options_hash[:reading] and (options_hash[:writing] or options_hash[:changing])
283     unless options_hash[:reading].eql?(options_hash[:writing]) or options_hash[:reading].eql?(options_hash[:changing])
284       raise Aquarium::Utils::InvalidOptions.new(":reading and :writing/:changing can only be used together if they refer to the same set of attributes.") 
285     end
286   end
287 end

Public Instance Methods

&(pointcut2)
Alias for: and
==(other)
Alias for: eql?
and(pointcut2) click to toggle source
   # File lib/aquarium/aspects/pointcut_composition.rb
24 def and pointcut2
25   result = Aquarium::Aspects::Pointcut.new
26   result.specification           = specification.and(pointcut2.specification) do |value1, value2| 
27     value1 & value2
28     # value1.intersection_using_eql_comparison value2
29   end
30   result.join_points_matched     = join_points_matched.intersection_using_eql_comparison      pointcut2.join_points_matched
31   result.join_points_not_matched = join_points_not_matched.intersection_using_eql_comparison  pointcut2.join_points_not_matched
32   result.candidate_types         = candidate_types.intersection          pointcut2.candidate_types
33   result.candidate_objects       = candidate_objects.intersection        pointcut2.candidate_objects
34   result
35 end
Also aliased as: intersection, &
empty?() click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
220 def empty?
221   return join_points_matched.empty? && join_points_not_matched.empty?
222 end
eql?(other) click to toggle source

Two Considered equivalent only if the same join points matched and not_matched sets are equal, the specifications are equal, and the candidate types and candidate objects are equal. if you care only about the matched join points, then just compare join_points_matched

    # File lib/aquarium/aspects/pointcut.rb
207 def eql? other
208   object_id == other.object_id || 
209   (self.class == other.class &&
210    specification == other.specification && 
211    candidate_types == other.candidate_types && 
212    candidate_types_excluded == other.candidate_types_excluded && 
213    candidate_objects == other.candidate_objects && 
214    join_points_matched == other.join_points_matched &&
215    join_points_not_matched == other.join_points_not_matched)
216 end
Also aliased as: ==
finish_specification_initialization() click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
263 def finish_specification_initialization
264   @specification.merge! Pointcut.make_attribute_reading_writing_options(@original_options)
265   # Map the method options to their canonical values:
266   @specification[:method_options] = Aquarium::Finders::MethodFinder.init_method_options(@specification[:method_options])
267   use_default_objects_if_defined unless any_type_related_options_given?
268   Pointcut::validate_attribute_options @specification, @original_options
269   init_methods_specification
270 end
init_methods_specification() click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
272 def init_methods_specification
273   match_all_methods if ((no_methods_specified? and no_attributes_specified?) or all_methods_specified?)
274 end
inspect() click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
224 def inspect
225   "Pointcut: {specification: #{specification.inspect}, candidate_types: #{candidate_types.inspect}, candidate_types_excluded: #{candidate_types_excluded.inspect}, candidate_objects: #{candidate_objects.inspect}, join_points_matched: #{join_points_matched.inspect}, join_points_not_matched: #{join_points_not_matched.inspect}}"
226 end
Also aliased as: to_s
intersection(pointcut2)
Alias for: and
or(pointcut2) click to toggle source
   # File lib/aquarium/aspects/pointcut_composition.rb
 9 def or pointcut2
10   result = Aquarium::Aspects::Pointcut.new
11   result.specification           = specification.or(pointcut2.specification) do |value1, value2| 
12     value1.union_using_eql_comparison value2
13   end
14   result.join_points_matched     = join_points_matched.union_using_eql_comparison     pointcut2.join_points_matched
15   result.join_points_not_matched = join_points_not_matched.union_using_eql_comparison pointcut2.join_points_not_matched
16   result.candidate_types         = candidate_types.union         pointcut2.candidate_types
17   result.candidate_objects       = candidate_objects.union       pointcut2.candidate_objects
18   result
19 end
Also aliased as: union, |
to_s()
Alias for: inspect
union(pointcut2)
Alias for: or
|(pointcut2)
Alias for: or

Protected Instance Methods

all_methods_specified?() click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
301 def all_methods_specified?
302   methods_spec = @specification[:methods].to_a
303   methods_spec.include?(:all) or methods_spec.include?(:all_methods)
304 end
match_all_methods() click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
293 def match_all_methods
294   @specification[:methods] = Set.new([:all])
295 end
no_attributes_specified?() click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
306 def no_attributes_specified?
307   @specification[:attributes].nil? or @specification[:attributes].empty?
308 end
no_methods_specified?() click to toggle source
    # File lib/aquarium/aspects/pointcut.rb
297 def no_methods_specified?
298   @specification[:methods].nil? or @specification[:methods].empty?
299 end