aquarium 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/Aquarium-IDEA.ipr +252 -0
  2. data/Aquarium-IDEA.iws +493 -0
  3. data/Aquarium.ipr +1 -1
  4. data/Aquarium.iws +133 -138
  5. data/CHANGES +63 -0
  6. data/ParseTreePlay.rb +25 -0
  7. data/README +55 -3
  8. data/RELEASE-PLAN +9 -1
  9. data/TODO.rb +175 -15
  10. data/examples/aspect_design_example.rb +13 -1
  11. data/examples/aspect_design_example_spec.rb +20 -2
  12. data/examples/introductions_example.rb +35 -0
  13. data/examples/introductions_example_spec.rb +37 -0
  14. data/examples/method_missing_example.rb +2 -1
  15. data/lib/aquarium/aspects/advice.rb +127 -74
  16. data/lib/aquarium/aspects/aspect.rb +139 -72
  17. data/lib/aquarium/aspects/default_objects_handler.rb +6 -4
  18. data/lib/aquarium/aspects/exclusion_handler.rb +15 -3
  19. data/lib/aquarium/aspects/join_point.rb +60 -55
  20. data/lib/aquarium/aspects/pointcut.rb +153 -124
  21. data/lib/aquarium/aspects/pointcut_composition.rb +1 -1
  22. data/lib/aquarium/dsl/aspect_dsl.rb +13 -5
  23. data/lib/aquarium/dsl/object_dsl.rb +4 -2
  24. data/lib/aquarium/extras/design_by_contract.rb +9 -5
  25. data/lib/aquarium/finders.rb +1 -0
  26. data/lib/aquarium/finders/finder_result.rb +13 -5
  27. data/lib/aquarium/finders/method_finder.rb +75 -70
  28. data/lib/aquarium/finders/pointcut_finder.rb +166 -0
  29. data/lib/aquarium/finders/type_finder.rb +104 -62
  30. data/lib/aquarium/utils/array_utils.rb +1 -1
  31. data/lib/aquarium/utils/invalid_options.rb +2 -0
  32. data/lib/aquarium/utils/name_utils.rb +3 -2
  33. data/lib/aquarium/utils/nil_object.rb +7 -3
  34. data/lib/aquarium/utils/options_utils.rb +38 -27
  35. data/lib/aquarium/utils/set_utils.rb +2 -2
  36. data/lib/aquarium/utils/type_utils.rb +11 -0
  37. data/lib/aquarium/version.rb +1 -1
  38. data/spec/aquarium/aspects/advice_spec.rb +147 -32
  39. data/spec/aquarium/aspects/aspect_invocation_spec.rb +252 -43
  40. data/spec/aquarium/aspects/aspect_spec.rb +148 -88
  41. data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +40 -34
  42. data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +39 -3
  43. data/spec/aquarium/aspects/join_point_spec.rb +190 -227
  44. data/spec/aquarium/aspects/pointcut_spec.rb +24 -1
  45. data/spec/aquarium/dsl/aspect_dsl_spec.rb +17 -17
  46. data/spec/aquarium/finders/method_finder_spec.rb +8 -2
  47. data/spec/aquarium/finders/pointcut_finder_spec.rb +193 -0
  48. data/spec/aquarium/finders/pointcut_finder_spec_test_classes.rb +90 -0
  49. data/spec/aquarium/finders/type_finder_spec.rb +17 -0
  50. data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +4 -4
  51. data/spec/aquarium/finders/type_finder_with_nested_types.rb +47 -0
  52. data/spec/aquarium/utils/nil_object_spec.rb +21 -0
  53. data/spec/aquarium/utils/type_utils_sample_nested_types.rb +51 -0
  54. data/spec/aquarium/utils/type_utils_spec.rb +18 -1
  55. metadata +13 -3
@@ -10,24 +10,35 @@ require File.dirname(__FILE__) + '/finder_result'
10
10
  # Finds types known to the runtime environment.
11
11
  module Aquarium
12
12
  module Finders
13
+ # == TypeFinder
14
+ # Locate types.
13
15
  class TypeFinder
14
16
  include Aquarium::Utils::ArrayUtils
15
17
  include Aquarium::Utils::TypeUtils
16
18
  include Aquarium::Utils::OptionsUtils
17
19
 
18
- def self.add_ancestors_and_descendents_option_variants_for option, options_hash
20
+ class TypeFinderResult < Aquarium::Finders::FinderResult
21
+ include Enumerable
22
+ def each
23
+ matched_keys.each { |x| yield x }
24
+ end
25
+ end
26
+
27
+ def self.add_ancestors_descendents_and_nested_option_variants_for option, options_hash
19
28
  all_variants = options_hash[option].dup
20
29
  options_hash["#{option}_and_descendents"] = all_variants.map {|x| "#{x}_and_descendents"}
21
30
  options_hash["#{option}_and_ancestors"] = all_variants.map {|x| "#{x}_and_ancestors"}
31
+ options_hash["#{option}_and_nested_types"] =
32
+ all_variants.map {|x| "#{x}_and_nested_types"} + all_variants.map {|x| "#{x}_and_nested"}
22
33
  end
23
34
 
24
35
  TYPE_FINDER_CANONICAL_OPTIONS = {
25
36
  "types" => %w[type class classes module modules name names],
26
37
  }
27
- # Add the ancestors and descendents first, then add all the preposition and exclude variants, so the latter
28
- # are added to the former...
38
+ # Add the ancestors, descendents, and nested variants first, then add all the preposition and
39
+ # exclude variants, so the latter are added to the former...
29
40
  TYPE_FINDER_CANONICAL_OPTIONS.keys.dup.each do |type_option|
30
- add_ancestors_and_descendents_option_variants_for type_option, TYPE_FINDER_CANONICAL_OPTIONS
41
+ add_ancestors_descendents_and_nested_option_variants_for type_option, TYPE_FINDER_CANONICAL_OPTIONS
31
42
  end
32
43
  TYPE_FINDER_CANONICAL_OPTIONS.keys.dup.each do |type_option|
33
44
  add_prepositional_option_variants_for type_option, TYPE_FINDER_CANONICAL_OPTIONS
@@ -39,60 +50,85 @@ module Aquarium
39
50
  canonical_options_given_methods CANONICAL_OPTIONS
40
51
  canonical_option_accessor CANONICAL_OPTIONS
41
52
 
42
- # Usage:
43
- # finder_result = TypeFinder.new.find [options => [...] ]
44
- # where
45
- # <tt>:types => types_and_type_names_and_regexps</tt>::
46
- # <tt>:names => types_and_type_names_and_regexps</tt>::
47
- # <tt>:type => types_and_type_names_and_regexps</tt>::
48
- # <tt>:name => types_and_type_names_and_regexps</tt>::
49
- # A single type or array of types, specified using any combination of the type
50
- # name strings, the type "constants" and/or regular expessions. The four different
51
- # flags are just "sugar" for each other.
53
+ # Returns a TypeFinder::TypeFinderResult, where the "matched" keys are the input
54
+ # types, type names, and/or regular expressions, and objects for which matches were found and the
55
+ # corresponding values are the class constant or variable pointcuts that were found.
56
+ # The keys in the "not_matched" part of the result are the specified types and objects
57
+ # for which no matches were found.
52
58
  #
53
- # <tt>:types_and_descendents => types_and_type_names_and_regexps</tt>::
54
- # <tt>:names_and_descendents => types_and_type_names_and_regexps</tt>::
55
- # <tt>:type_and_descendents => types_and_type_names_and_regexps</tt>::
56
- # <tt>:name_and_descendents => types_and_type_names_and_regexps</tt>::
59
+ # The options are as follows:
57
60
  #
58
- # Same as for <tt>:types</tt> <i>etc.</i>, but also match their descendents.
61
+ # ==== Types
62
+ # A single type, type name, name regular expression, or an array of the same. (Mixed allowed.)
63
+ # * <tt>:types => types_and_type_names_and_regexps</tt>
64
+ # * <tt>:names => types_and_type_names_and_regexps</tt>
65
+ # * <tt>:type => types_and_type_names_and_regexps</tt>
66
+ # * <tt>:name => types_and_type_names_and_regexps</tt>
59
67
  #
60
- # <tt>:types_and_ancestors => types_and_type_names_and_regexps</tt>::
61
- # <tt>:names_and_ancestors => types_and_type_names_and_regexps</tt>::
62
- # <tt>:type_and_ancestors => types_and_type_names_and_regexps</tt>::
63
- # <tt>:name_and_ancestors => types_and_type_names_and_regexps</tt>::
68
+ # ==== Types and Descendents
69
+ # A single type, type name, name regular expression, or an array of the same. (Mixed allowed.)
70
+ # Matching types and their descendents will be found. A type that includes a module is considered
71
+ # a descendent, since the module would show up in that type's ancestors.
72
+ # * <tt>:types_and_descendents => types_and_type_names_and_regexps</tt>
73
+ # * <tt>:names_and_descendents => types_and_type_names_and_regexps</tt>
74
+ # * <tt>:type_and_descendents => types_and_type_names_and_regexps</tt>
75
+ # * <tt>:name_and_descendents => types_and_type_names_and_regexps</tt>
64
76
  #
65
- # Same as for <tt>:types</tt> <i>etc.</i>, but also match their ancestors.
66
- # This option will also match <tt>Class</tt>, <tt>Module</tt>, <i>etc.</>,
77
+ # ==== Types and Ancestors
78
+ # A single type, type name, name regular expression, or an array of the same. (Mixed allowed.)
79
+ # Matching types and their ancestors will be found.
80
+ # * <tt>:types_and_ancestors => types_and_type_names_and_regexps</tt>
81
+ # * <tt>:names_and_ancestors => types_and_type_names_and_regexps</tt>
82
+ # * <tt>:type_and_ancestors => types_and_type_names_and_regexps</tt>
83
+ # * <tt>:name_and_ancestors => types_and_type_names_and_regexps</tt>
84
+ #
85
+ # ==== Types and Nested Types
86
+ # A single type, type name, name regular expression, or an array of the same. (Mixed allowed.)
87
+ # Matching types and any types nested within them will be found.
88
+ # * <tt>:types_and_nested_types => types_and_type_names_and_regexps</tt>
89
+ # * <tt>:names_and_nested_types => types_and_type_names_and_regexps</tt>
90
+ # * <tt>:type_and_nested_types => types_and_type_names_and_regexps</tt>
91
+ # * <tt>:name_and_nested_types => types_and_type_names_and_regexps</tt>
92
+ # * <tt>:types_and_nested => types_and_type_names_and_regexps</tt>
93
+ # * <tt>:names_and_nested => types_and_type_names_and_regexps</tt>
94
+ # * <tt>:type_and_nested => types_and_type_names_and_regexps</tt>
95
+ # * <tt>:name_and_nested => types_and_type_names_and_regexps</tt>
96
+ #
97
+ # Note: This option will also match <tt>Class</tt>, <tt>Module</tt>, <i>etc.</>,
67
98
  # so use with caution!
68
99
  #
69
100
  # To get both descendents and ancestors, use both options with the same type
70
101
  # specification.
71
102
  #
72
- # The "other options" include the following:
73
- #
103
+ # ==== Exclude Types
104
+ # Exclude the specified type(s) from the list of matched types.
105
+ # Note: These excluded types <i>won't</i> appear in the FinderResult#not_matched.
106
+ # * <tt>:exclude_type => types_and_type_names_and_regexps</tt>
107
+ # * <tt>:exclude_types => types_and_type_names_and_regexps</tt>
108
+ # * <tt>:exclude_name => types_and_type_names_and_regexps</tt>
109
+ # * <tt>:exclude_names => types_and_type_names_and_regexps</tt>
110
+ # * <tt>:exclude_types_and_descendents => types_and_type_names_and_regexps</tt>
111
+ # * <tt>:exclude_names_and_descendents => types_and_type_names_and_regexps</tt>
112
+ # * <tt>:exclude_type_and_descendents => types_and_type_names_and_regexps</tt>
113
+ # * <tt>:exclude_name_and_descendents => types_and_type_names_and_regexps</tt>
114
+ # * <tt>:exclude_types_and_ancestors => types_and_type_names_and_regexps</tt>
115
+ # * <tt>:exclude_names_and_ancestors => types_and_type_names_and_regexps</tt>
116
+ # * <tt>:exclude_type_and_ancestors => types_and_type_names_and_regexps</tt>
117
+ # * <tt>:exclude_name_and_ancestors => types_and_type_names_and_regexps</tt>
118
+ # * <tt>:exclude_types_and_nested_types => types_and_type_names_and_regexps</tt>
119
+ # * <tt>:exclude_names_and_nested_types => types_and_type_names_and_regexps</tt>
120
+ # * <tt>:exclude_type_and_nested_types => types_and_type_names_and_regexps</tt>
121
+ # * <tt>:exclude_name_and_nested_types => types_and_type_names_and_regexps</tt>
122
+ # * <tt>:exclude_types_and_nested => types_and_type_names_and_regexps</tt>
123
+ # * <tt>:exclude_names_and_nested => types_and_type_names_and_regexps</tt>
124
+ # * <tt>:exclude_type_and_nested => types_and_type_names_and_regexps</tt>
125
+ # * <tt>:exclude_name_and_nested => types_and_type_names_and_regexps</tt>
74
126
  #
75
- # <tt>:exclude_type => types_and_type_names_and_regexps</tt>::
76
- # <tt>:exclude_types => types_and_type_names_and_regexps</tt>::
77
- # <tt>:exclude_name => types_and_type_names_and_regexps</tt>::
78
- # <tt>:exclude_names => types_and_type_names_and_regexps</tt>::
79
- # Exclude the specified type or list of types from the list of matched types.
80
- # These excluded types <b>won't</b> appear in the FinderResult#not_matched.
81
- #
82
- # <tt>:exclude_types_and_descendents => types_and_type_names_and_regexps</tt>::
83
- # <tt>:exclude_names_and_descendents => types_and_type_names_and_regexps</tt>::
84
- # <tt>:exclude_type_and_descendents => types_and_type_names_and_regexps</tt>::
85
- # <tt>:exclude_name_and_descendents => types_and_type_names_and_regexps</tt>::
86
- #
87
- # <tt>:exclude_types_and_ancestors => types_and_type_names_and_regexps</tt>::
88
- # <tt>:exclude_names_and_ancestors => types_and_type_names_and_regexps</tt>::
89
- # <tt>:exclude_type_and_ancestors => types_and_type_names_and_regexps</tt>::
90
- # <tt>:exclude_name_and_ancestors => types_and_type_names_and_regexps</tt>::
91
- #
92
- # Exclude the descendents or ancestors, as well.
93
- #
94
- # Because of the special sigificance of the module ("namespace") separator "::", the rules
95
- # for the regular expressions are as follows. Assume that "subexp" is a "sub regular
127
+ # ==== Namespaces (Modules) and Regular Expressions
128
+ # Because of the special sigificance of the module ("namespace") separator "::",
129
+ # special rules for the regular expressions apply. Normally, you can just use the
130
+ # "*_and_nested_types" or "*_and_nested" to match enclosed types, but if you want to
131
+ # be selective, note the following. First, assume that "subexp" is a "sub regular
96
132
  # expression" that results if you split on the separator "::".
97
133
  #
98
134
  # A full regexp with no "::"::
@@ -121,8 +157,7 @@ module Aquarium
121
157
  result
122
158
  end
123
159
 
124
-
125
- protected
160
+ private
126
161
 
127
162
  # Hack. Since the finder could be reused, unset the specification created by #find.
128
163
  def unset_specification
@@ -130,9 +165,9 @@ module Aquarium
130
165
  end
131
166
 
132
167
  def do_find_types
133
- result = Aquarium::Finders::FinderResult.new
134
- excluded = Aquarium::Finders::FinderResult.new
168
+ result = TypeFinderResult.new
135
169
  return result if noop
170
+ excluded = TypeFinderResult.new
136
171
  @specification.each do |option, types|
137
172
  next unless TYPE_FINDER_CANONICAL_OPTIONS.keys.include?(option.to_s)
138
173
  next if types.nil? or types.empty?
@@ -145,7 +180,7 @@ module Aquarium
145
180
  end
146
181
 
147
182
  def find_matching regexpes_or_names, option
148
- result = Aquarium::Finders::FinderResult.new
183
+ result = TypeFinderResult.new
149
184
  expressions = make_array regexpes_or_names
150
185
  expressions.each do |expression|
151
186
  expr = strip expression
@@ -210,34 +245,41 @@ module Aquarium
210
245
  end
211
246
 
212
247
  def finish_and_make_successful_result found, option
213
- all = prettify(found + handle_ancestors_and_descendents(found, option))
248
+ all = prettify(found + handle_ancestors_descendents_and_nested(found, option))
214
249
  hash = make_return_hash(all)
215
- Aquarium::Finders::FinderResult.new hash
250
+ TypeFinderResult.new hash
216
251
  end
217
252
 
218
253
  def make_failed_result name
219
- Aquarium::Finders::FinderResult.new :not_matched => {name => Set.new([])}
254
+ TypeFinderResult.new :not_matched => {name => Set.new([])}
220
255
  end
221
256
 
222
- def handle_ancestors_and_descendents types, option
257
+ def handle_ancestors_descendents_and_nested types, option
223
258
  result = []
224
- result << add_descendents(types) if should_find_descendents(option)
225
259
  result << add_ancestors(types) if should_find_ancestors(option)
260
+ result << add_descendents(types) if should_find_descendents(option)
261
+ result << add_nested(types) if should_find_nested(option)
226
262
  result
227
263
  end
228
264
 
265
+ def add_ancestors types
266
+ types.inject([]) { |memo, t| memo << t.ancestors }
267
+ end
229
268
  def add_descendents types
230
269
  types.inject([]) { |memo, t| memo << Aquarium::Utils::TypeUtils.descendents(t) }
231
270
  end
232
- def add_ancestors types
233
- types.inject([]) { |memo, t| memo << t.ancestors }
271
+ def add_nested types
272
+ types.inject([]) { |memo, t| memo << Aquarium::Utils::TypeUtils.nested(t) }
234
273
  end
235
274
 
275
+ def should_find_ancestors option
276
+ option.to_s.include? "_ancestors"
277
+ end
236
278
  def should_find_descendents option
237
279
  option.to_s.include? "_descendents"
238
280
  end
239
- def should_find_ancestors option
240
- option.to_s.include? "_ancestors"
281
+ def should_find_nested option
282
+ option.to_s.include? "_nested"
241
283
  end
242
284
 
243
285
 
@@ -8,7 +8,7 @@ module Aquarium
8
8
  # Return an array containing the input item or list of items. If the input
9
9
  # is an array, it is returned. In all cases, the constructed array is a
10
10
  # flattened version of the input and any nil elements are removed by #strip_array_nils.
11
- # Note that this behavior effectively converts +nil+ to +[]+.
11
+ # Note that this behavior effectively converts <tt>nil</tt> to <tt>[]</tt>.
12
12
  def make_array *value_or_enum
13
13
  ArrayUtils.make_array value_or_enum
14
14
  end
@@ -1,5 +1,7 @@
1
1
  module Aquarium
2
2
  module Utils
3
+ # == Invalid Options
4
+ # The exception thrown when invalid options to any API methods are detected.
3
5
  class InvalidOptions < Exception
4
6
  def initialize *args
5
7
  super
@@ -1,9 +1,10 @@
1
1
  require 'aquarium/utils/type_utils'
2
2
 
3
- # Convert various strings, symbols, object ids, etc. into valid "names" that
4
- # can be used as method names, etc.
5
3
  module Aquarium
6
4
  module Utils
5
+ # == NameUtils
6
+ # Convert various strings, symbols, object ids, etc. into valid "names" that
7
+ # can be used as method names, etc.
7
8
  module NameUtils
8
9
 
9
10
  @@char_expr_map = {
@@ -1,10 +1,14 @@
1
- # One implementation of the Null Object Pattern (renamed "Nil" for Ruby).
2
- # All methods not defined by Object simply return the Aquarium::Utils::NilObject itself.
3
- # Users can subclass or add methods to instances to customize the behavior.
4
1
 
5
2
  module Aquarium
6
3
  module Utils
4
+ # An implementation of the Null Object Pattern (renamed "Nil" for Ruby).
5
+ # All methods not defined by Object simply return the Aquarium::Utils::NilObject itself.
6
+ # Users can subclass or add methods to instances to customize the behavior.
7
7
  class Aquarium::Utils::NilObject
8
+
9
+ def eql? other
10
+ other.kind_of? NilObject
11
+ end
8
12
 
9
13
  def method_missing method_sym, *args
10
14
  self
@@ -4,54 +4,64 @@ require 'aquarium/utils/default_logger'
4
4
  module Aquarium
5
5
  module Utils
6
6
 
7
+ # == OptionsUtils
7
8
  # Support parsing and processing of key-value pairs of options, where the values are always converted
8
- # to sets.
9
+ # to Sets.
9
10
  # Types including this module should have their <tt>initialize</tt> methods call this module's
10
- # <tt>init_specification</tt>
11
- # to do the options processing. See its documentation for more details.
11
+ # #init_specification to do the options processing. See its documentation for more details.
12
+ #
13
+ # Several <i>class</i> methods are included for defining convenience <i>instance</i> methods.
14
+ # For example, for options <tt>:foo</tt> and <tt>:bar</tt>, calling:
15
+ #
16
+ # canonical_options_given_methods :foo, :bar
12
17
  #
13
- # Several class methods are included in including types for defining convenience instance methods.
14
- # for options +:foo+ and +:bar+, calling:
15
- # <tt>canonical_options_given_methods :foo, :bar</tt>
16
18
  # will define several methods for each option specified, e.g.,:
17
- # <tt>foo_given? # => returns true if a value was specified for the :foo option</tt>
18
- # <tt>foo_given # => returns the value of @specification[:foo]</tt>
19
- # <tt>bar_given? # etc.
20
- # <tt>bar_given
19
+ #
20
+ # foo_given # => returns the value of @specification[:foo]
21
+ # foo_given? # => returns true "foo_given" is not nil or empty.
22
+ # bar_given # etc...
23
+ # bar_given?
24
+ #
21
25
  # If you would like corresponding reader and writer methods, pass a list of the keys for which you want these
22
- # methods defined to
23
- # <tt>canonical_option_reader :foo, :bar # analogous to attr_reader
24
- # <tt>canonical_option_writer :foo, :bar # analogous to attr_writer
25
- # <tt>canonical_option_accessor :foo, :bar # analogous to attr_accessor
26
- # For all of these methods, you can also pass CANONICAL_OPTIONS (discussed below) to define methods
27
- # for all of the "canonical" options. _E.g.,_
28
- # <tt>canonical_option_accessor CANONICAL_OPTIONS
26
+ # methods defined to one of the following methods:
27
+ #
28
+ # canonical_option_reader :foo, :bar # analogous to attr_reader
29
+ # canonical_option_writer :foo, :bar # analogous to attr_writer
30
+ # canonical_option_accessor :foo, :bar # analogous to attr_accessor
31
+ #
32
+ # For all of these methods, you can also pass <tt>CANONICAL_OPTIONS</tt> (discussed below) to define methods
33
+ # for all of the "canonical" options, <i>e.g.,</i>
34
+ #
35
+ # canonical_option_accessor CANONICAL_OPTIONS
29
36
  #
30
37
  # These methods are not defined by default to prevent accidentally overriding other methods that you might
31
38
  # have defined with the same names. Also, note that the writer methods will convert the inputs to sets,
32
39
  # following the conventions for the options and the readers will return the sets. If you want different handling,
33
- # you'll have to provide custom implementations. Note that special-case accessor methods are already defined
34
- # for the :noop and :logger options (discussed below) where the writers expect single values, not sets, and the
35
- # readers return the single values.
36
- # Finally, these +canonical_option_*+ methods should only be called with the *keys* for the +CANONICAL_OPTIONS+.
40
+ # you'll have to provide custom implementations.
41
+ #
42
+ # Note that special-case accessor methods are already defined for the <tt>:noop</tt> and <tt>:logger</tt>
43
+ # options (discussed below) where the writers expect single values, not sets, and the
44
+ # readers return the single values. (Yea, it's a bit inconsistent...)
45
+ #
46
+ # Finally, these <tt>canonical_option_*</tt> methods should only be called with the *keys* for the +CANONICAL_OPTIONS+.
37
47
  # The keys are considered the "canonical options", while the values for the keys are synonyms that can be used instead.
38
48
  #
39
49
  # This module also defines several universal options that will be available to all types that include this module:
40
- # <tt>:logger</tt>
50
+ # <tt>:logger</tt>::
41
51
  # A Ruby standard library Logger used for any messages. A default system-wide logger is used otherwise.
42
52
  # The corresponding <tt>logger</tt> and <tt>logger=</tt> accessors are defined.
43
53
  #
44
- # <tt>:logger_stream</tt>
54
+ # <tt>:logger_stream</tt>::
45
55
  # An an alternative to defining the logger, you can define just the output stream where log output will be written.
46
56
  # If this option is specified, a new logger will be created for the instance with this output stream.
47
57
  # There are no corresponding accessors; use the appropriate methods on the <tt>logger</tt> object instead.
48
58
  #
49
- # <tt>:severity</tt>
59
+ # <tt>:severity</tt>::
50
60
  # The logging severity level, one of the Logger::Severity values or a corresponding integer value.
51
61
  # If this option is specified, a new logger will be created for the instance with this output stream.
52
62
  # There are no corresponding accessors; use the corresponding methods on the <tt>logger</tt> object instead.
53
63
  #
54
- # <tt>:noop => options_hash[:noop] || false</tt>
64
+ # <tt>:noop => options_hash[:noop] || false</tt>::
55
65
  # If true, don't do "anything", the interpretation of which will vary with the type receiving the option.
56
66
  # For example, a type might go through some initialization, such as parsng its options, but
57
67
  # do nothing after that. Primarily useful for debugging and testing.
@@ -199,7 +209,8 @@ module Aquarium
199
209
  end
200
210
  end
201
211
 
202
- protected
212
+ private
213
+
203
214
  def determine_options_for_accessors canonical_option_key_list
204
215
  keys = canonical_option_key_list
205
216
  if canonical_option_key_list.kind_of?(Array) and canonical_option_key_list.size == 1
@@ -217,7 +228,7 @@ module Aquarium
217
228
  ClassMethods.send :append_features, (class << clazz; self; end)
218
229
  end
219
230
 
220
- protected
231
+ private
221
232
 
222
233
  def all_allowed_option_symbols
223
234
  @canonical_options.to_a.flatten.map {|o| o.intern} + @additional_allowed_options
@@ -7,14 +7,14 @@ module Aquarium
7
7
  # Return a set containing the input item or list of items. If the input
8
8
  # is a set or an array, it is returned. In all cases, the constructed set is a
9
9
  # flattened version of the input and any nil elements are removed by #strip_set_nils.
10
- # Note that this behavior effectively converts +nil+ to +[]+.
10
+ # Note that this behavior effectively converts <tt>nil</tt> to <tt>[]</tt>.
11
11
  def make_set *value_or_set_or_array
12
12
  strip_set_nils(convert_to_set(*value_or_set_or_array))
13
13
  end
14
14
 
15
15
  # Return a new set that is a copy of the input set with all nils removed.
16
16
  def strip_set_nils set
17
- set.delete_if {|x| x.nil?}
17
+ SetUtils.strip_set_nils set
18
18
  end
19
19
 
20
20
  # Return a new set that is a copy of the input set with all nils removed.
@@ -18,6 +18,17 @@ module Aquarium
18
18
  result.uniq
19
19
  end
20
20
 
21
+ def self.nested clazz
22
+ result = [clazz]
23
+ clazz.constants.each do |const|
24
+ mod = clazz.class_eval(const)
25
+ next unless is_type?(mod)
26
+ result << mod
27
+ result << nested(mod)
28
+ end
29
+ result.flatten.uniq
30
+ end
31
+
21
32
  protected
22
33
 
23
34
  # For JRuby classes, we have to "__x__" forms of the reflection methods that don't end in '?'.
@@ -9,7 +9,7 @@ module Aquarium
9
9
  unless defined? MAJOR
10
10
  MAJOR = 0
11
11
  MINOR = 4
12
- TINY = 1
12
+ TINY = 2
13
13
  RELEASE_CANDIDATE = nil
14
14
 
15
15
  # RANDOM_TOKEN: 0.598704893979657