cascading-configuration-hash 1.4.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (19) hide show
  1. data/lib/cascading-configuration-hash/CascadingConfiguration/Hash/Interface.rb +86 -27
  2. data/lib/cascading-configuration-hash/CascadingConfiguration/Hash.rb +5 -21
  3. data/lib/cascading-configuration-hash/{CascadingConfiguration → _private_/CascadingConfiguration/Hash/CompositingHash}/LocalConfigurationHash.rb +29 -2
  4. data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/CompositingHash.rb +246 -0
  5. data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/Interface/GettersSetters.rb +233 -0
  6. data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/ModuleSupportMethods.rb +29 -0
  7. data/lib/cascading-configuration-hash.rb +12 -23
  8. data/spec/CascadingConfiguration/Hash_spec.rb +2 -3
  9. data/spec/{CascadingConfiguration → _private_/CascadingConfiguration/Hash/CompositingHash}/LocalConfigurationHash_spec.rb +9 -9
  10. data/spec/_private_/CascadingConfiguration/Hash/CompositingHash_spec.rb +347 -0
  11. metadata +10 -28
  12. data/lib/cascading-configuration-hash/CascadingConfiguration/CompositingHash/Instance.rb +0 -31
  13. data/lib/cascading-configuration-hash/CascadingConfiguration/CompositingHash.rb +0 -135
  14. data/lib/cascading-configuration-hash/CascadingConfiguration/Hash/AccessorDefinitionMethods.rb +0 -149
  15. data/lib/cascading-configuration-hash/CascadingConfiguration/Hash/Interface/Instance.rb +0 -26
  16. data/lib/cascading-configuration-hash/CascadingConfiguration/_private_/CompositingHash.rb +0 -79
  17. data/lib/cascading-configuration-hash/CascadingConfiguration/_private_/LocalConfigurationHash.rb +0 -31
  18. data/spec/CascadingConfiguration/CascadingCompositeHash_spec.rb +0 -416
  19. data/spec/CascadingConfiguration/Hash/AccessorDefinitionMethods_spec.rb +0 -30
@@ -1,7 +1,8 @@
1
1
 
2
2
  module CascadingConfiguration::Hash::Interface
3
3
 
4
- extend CascadingConfiguration::InternalModuleStub
4
+ # Support methods that define configuration settings hash methods
5
+ include ::CascadingConfiguration::Hash::Interface::GettersSetters
5
6
 
6
7
  #############################
7
8
  # attr_configuration_hash #
@@ -9,14 +10,22 @@ module CascadingConfiguration::Hash::Interface
9
10
 
10
11
  # defines configuration in class or module
11
12
  # configuration cascades downward to instance including all classes or modules in-between
12
- def attr_configuration_hash( *property_names, & compositing_block )
13
+ def attr_configuration_hash( *configuration_names, & compositing_block )
13
14
 
14
- property_names.each do |this_property_name|
15
- accessor_module_support.set_compositing_proc( this_property_name, compositing_block ) if block_given?
15
+ configuration_names.each do |this_configuration_name|
16
+ if block_given?
17
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
18
+ for_instance = false
19
+ if ! is_a?( Module ) and ! module_configuration_support_module
20
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
21
+ for_instance = true
22
+ end
23
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
24
+ end
16
25
  # define configuration setter
17
- define_cascading_hash_setter( this_property_name )
26
+ define_cascading_hash_setter( this_configuration_name )
18
27
  # define configuration getter
19
- define_cascading_hash_getter( this_property_name )
28
+ define_cascading_hash_getter( this_configuration_name )
20
29
  end
21
30
 
22
31
  return self
@@ -29,14 +38,22 @@ module CascadingConfiguration::Hash::Interface
29
38
 
30
39
  # defines configuration in class or module
31
40
  # configuration cascades downward to last class or module
32
- def attr_module_configuration_hash( *property_names, & compositing_block )
41
+ def attr_module_configuration_hash( *configuration_names, & compositing_block )
33
42
 
34
- property_names.each do |this_property_name|
35
- accessor_module_support.set_compositing_proc( this_property_name, compositing_block ) if block_given?
43
+ configuration_names.each do |this_configuration_name|
44
+ if block_given?
45
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
46
+ for_instance = false
47
+ if ! is_a?( Module ) and ! module_configuration_support_module
48
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
49
+ for_instance = true
50
+ end
51
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
52
+ end
36
53
  # define configuration setter
37
- define_class_configuration_hash_setter( this_property_name )
54
+ define_class_configuration_hash_setter( this_configuration_name )
38
55
  # define configuration getter
39
- define_class_configuration_hash_getter( this_property_name )
56
+ define_class_configuration_hash_getter( this_configuration_name )
40
57
  end
41
58
 
42
59
  return self
@@ -50,19 +67,25 @@ module CascadingConfiguration::Hash::Interface
50
67
 
51
68
  # defines configuration in present class or module context
52
69
  # configuration does not cascade
53
- def attr_local_configuration_hash( *property_names, & compositing_block )
54
-
55
- CascadingConfiguration::Variable.define_accessor_local_instance_support( self )
56
-
57
- property_names.each do |this_property_name|
58
- accessor_module_support.set_compositing_proc( this_property_name, compositing_block ) if block_given?
70
+ def attr_local_configuration_hash( *configuration_names, & compositing_block )
71
+
72
+ CascadingConfiguration::Variable.initialize_local_instance_configuration_module( self )
73
+
74
+ configuration_names.each do |this_configuration_name|
75
+ if block_given?
76
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
77
+ for_instance = false
78
+ if ! is_a?( Module ) and ! module_configuration_support_module
79
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
80
+ for_instance = true
81
+ end
82
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
83
+ end
59
84
  # define configuration setter
60
- define_local_configuration_hash_setter( this_property_name )
85
+ define_local_configuration_hash_setter( this_configuration_name )
61
86
  # define configuration getter
62
- define_local_configuration_hash_getter( this_property_name )
87
+ define_local_configuration_hash_getter( this_configuration_name )
63
88
  end
64
-
65
- CascadingConfiguration::Variable.cascade_local_instance( self )
66
89
 
67
90
  return self
68
91
 
@@ -74,16 +97,52 @@ module CascadingConfiguration::Hash::Interface
74
97
 
75
98
  # defines configuration in present class or module context
76
99
  # configuration does not cascade
77
- def attr_object_configuration_hash( *property_names, & compositing_block )
100
+ def attr_object_configuration_hash( *configuration_names, & compositing_block )
101
+
102
+ CascadingConfiguration::Variable.initialize_local_instance_configuration_module( self )
103
+
104
+ configuration_names.each do |this_configuration_name|
105
+ if block_given?
106
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
107
+ for_instance = false
108
+ if ! is_a?( Module ) and ! module_configuration_support_module
109
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
110
+ for_instance = true
111
+ end
112
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
113
+ end
114
+ # define configuration setter
115
+ define_object_configuration_hash_setter( this_configuration_name )
116
+ # define configuration getter
117
+ define_object_configuration_hash_getter( this_configuration_name )
118
+ end
119
+
120
+ return self
121
+
122
+ end
78
123
 
79
- CascadingConfiguration::Variable.define_accessor_local_instance_support( self )
124
+ ######################################
125
+ # attr_instance_configuration_hash #
126
+ ######################################
80
127
 
81
- property_names.each do |this_property_name|
82
- accessor_module_support.set_compositing_proc( this_property_name, compositing_block ) if block_given?
128
+ # defines configuration in present class or module context
129
+ # configuration does not cascade
130
+ def attr_instance_configuration_hash( *configuration_names, & compositing_block )
131
+
132
+ configuration_names.each do |this_configuration_name|
133
+ if block_given?
134
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
135
+ for_instance = false
136
+ if ! is_a?( Module ) and ! module_configuration_support_module
137
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
138
+ for_instance = true
139
+ end
140
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
141
+ end
83
142
  # define configuration setter
84
- define_object_configuration_hash_setter( this_property_name )
143
+ define_instance_configuration_hash_setter( this_configuration_name )
85
144
  # define configuration getter
86
- define_object_configuration_hash_getter( this_property_name )
145
+ define_instance_configuration_hash_getter( this_configuration_name )
87
146
  end
88
147
 
89
148
  return self
@@ -1,28 +1,12 @@
1
1
 
2
2
  module CascadingConfiguration::Hash
3
3
 
4
- extend ModuleCluster
5
-
6
- extend CascadingConfiguration::InternalModuleStub
7
-
8
- include CascadingConfiguration::Variable
9
-
10
- include CascadingConfiguration::CompositingHash::Instance
11
- include CascadingConfiguration::Hash::Interface
12
- include CascadingConfiguration::Hash::AccessorDefinitionMethods
4
+ # Configuration modules for storage of settings hashes
5
+ include ::CascadingConfiguration::Variable
13
6
 
14
- prepend_module_include do |class_or_module|
15
- class_or_module.extend_also_extends( CascadingConfiguration::Variable::EigenclassConfigurationChain )
16
- end
7
+ # Interface to declare configuration settings hashes
8
+ include ::CascadingConfiguration::Hash::Interface
17
9
 
18
- include_cascades_extends( CascadingConfiguration::Hash::Interface::Instance )
19
-
20
- include_cascades_extends( CascadingConfiguration::Hash )
10
+ extend ::CascadingConfiguration::Hash::ModuleSupportMethods
21
11
 
22
- prepend_module_include do |class_or_module|
23
- class_or_module.include_or_extend_cascades_prepending_extends do
24
- accessor_module_support
25
- end
26
- end
27
-
28
12
  end
@@ -1,6 +1,6 @@
1
1
 
2
- class CascadingConfiguration::LocalConfigurationHash < Hash
3
-
2
+ class CascadingConfiguration::Hash::CompositingHash::LocalConfigurationHash < Hash
3
+
4
4
  attr_accessor :exclude_array
5
5
 
6
6
  ################
@@ -80,4 +80,31 @@ class CascadingConfiguration::LocalConfigurationHash < Hash
80
80
  super
81
81
  end
82
82
 
83
+ ###########################################################################################################
84
+ private ###############################################################################################
85
+ ###########################################################################################################
86
+
87
+ ##########################
88
+ # add_to_exclude_array #
89
+ ##########################
90
+
91
+ def add_to_exclude_array( *elements )
92
+ @exclude_array ||= ::Array.new
93
+ @exclude_array += elements
94
+ @exclude_array.sort!.uniq!
95
+ end
96
+
97
+ ###############################
98
+ # remove_from_exclude_array #
99
+ ###############################
100
+
101
+ def remove_from_exclude_array( *elements )
102
+ if @exclude_array
103
+ @exclude_array -= elements
104
+ @exclude_array.sort!.uniq!
105
+ else
106
+ @exclude_array ||= ::Array.new
107
+ end
108
+ end
109
+
83
110
  end
@@ -0,0 +1,246 @@
1
+
2
+ class CascadingConfiguration::Hash::CompositingHash < Hash
3
+
4
+ attr_accessor :local_cascading_hash
5
+
6
+ ################
7
+ # initialize #
8
+ ################
9
+
10
+ def initialize( configuration_instance, configuration_name )
11
+
12
+ for_instance = false
13
+
14
+ @configuration_instance = configuration_instance
15
+
16
+ module_configuration_module = ::CascadingConfiguration::Variable.module_configuration_support_module( configuration_instance )
17
+ if ! module_configuration_module and ! configuration_instance.is_a?( Module )
18
+ module_configuration_module = ::CascadingConfiguration::Variable.module_configuration_support_module( configuration_instance.class )
19
+ for_instance = true
20
+ end
21
+
22
+ @configuration_name = configuration_name
23
+
24
+ # store self for sub composites
25
+ module_configuration_module.set_configuration_variable( configuration_name, self, for_instance )
26
+
27
+ # if first ancestor can have a composite hash, register self with it in case it gets updated in the future
28
+ super_configuration_module = nil
29
+ if for_instance
30
+ super_configuration_module = module_configuration_module
31
+ else
32
+ super_configuration_module = module_configuration_module.super_configuration_module
33
+ end
34
+
35
+ if super_configuration_module and
36
+ @super_composite_hash = super_configuration_module.get_configuration_variable( configuration_name ) and
37
+ @super_composite_hash.respond_to?( :register_sub_composite_hash )
38
+
39
+ @super_composite_hash.register_sub_composite_hash( self )
40
+
41
+ end
42
+
43
+ # instantiate local cascading hash
44
+ @local_cascading_hash = ::CascadingConfiguration::Hash::CompositingHash::LocalConfigurationHash.new
45
+
46
+ # we may later have our own child composites that register with us
47
+ @sub_composite_hashes = ::Array.new
48
+
49
+ # initialize self status for parent and local
50
+ update_self_as_cascading_composite
51
+
52
+ end
53
+
54
+ #################################
55
+ # register_sub_composite_hash #
56
+ #################################
57
+
58
+ def register_sub_composite_hash( sub_composite_hash )
59
+ @sub_composite_hashes.push( sub_composite_hash )
60
+ return self
61
+ end
62
+
63
+ ###################################
64
+ # unregister_sub_composite_hash #
65
+ ###################################
66
+
67
+ def unregister_sub_composite_hash( sub_composite_hash )
68
+ @sub_composite_hashes.delete( sub_composite_hash )
69
+ return self
70
+ end
71
+
72
+ #########
73
+ # []= #
74
+ #########
75
+
76
+ def []=( key, value )
77
+ @local_cascading_hash[ key ] = value
78
+ update_adding_composite_elements( key => value )
79
+ end
80
+ alias_method :store, :[]=
81
+
82
+ ############
83
+ # delete #
84
+ ############
85
+
86
+ alias_method :super_delete, :delete
87
+ def delete( key )
88
+ value = self[ key ]
89
+ @local_cascading_hash.delete( key )
90
+ update_removing_composite_elements( key )
91
+ return value
92
+ end
93
+
94
+ ############
95
+ # merge! #
96
+ ############
97
+
98
+ alias_method :super_merge!, :merge!
99
+ def merge!( other_hash )
100
+ @local_cascading_hash.merge!( other_hash )
101
+ update_adding_composite_elements( other_hash )
102
+ return self
103
+ end
104
+
105
+ #############
106
+ # replace #
107
+ #############
108
+
109
+ alias_method :super_replace, :replace
110
+ def replace( other_hash )
111
+ # clear current values
112
+ clear
113
+ # merge replacement settings
114
+ merge!( other_hash )
115
+ update_self_as_cascading_composite
116
+ return self
117
+ end
118
+
119
+ ###########
120
+ # shift #
121
+ ###########
122
+
123
+ def shift
124
+ element = super
125
+ key = element[ 0 ]
126
+ @local_cascading_hash.delete( key )
127
+ update_removing_composite_elements( key )
128
+ return element
129
+ end
130
+
131
+ ###########
132
+ # clear #
133
+ ###########
134
+
135
+ alias_method :super_clear, :clear
136
+ def clear
137
+ # add all existing values to exclude array
138
+ keys.each do |this_key|
139
+ delete( this_key )
140
+ end
141
+ update_removing_composite_elements( *self.keys )
142
+ return self
143
+ end
144
+
145
+ #############
146
+ # freeze! #
147
+ #############
148
+
149
+ # freezes configuration and prevents ancestors from changing this configuration in the future
150
+ def freeze!
151
+
152
+ # move current configuration into local configuration
153
+ @local_cascading_hash.replace( self )
154
+
155
+ # unregister with parent composite so we don't get future updates from it
156
+ @super_composite_hash.unregister_sub_composite_hash( self ) if @super_composite_hash
157
+
158
+ return self
159
+
160
+ end
161
+
162
+ ###########################################################################################################
163
+ private ###############################################################################################
164
+ ###########################################################################################################
165
+
166
+ ########################################
167
+ # update_self_as_cascading_composite #
168
+ ########################################
169
+
170
+ def update_self_as_cascading_composite
171
+ # start fresh
172
+ super_clear
173
+ update_composite_self_for_parent_hash( @super_composite_hash, @local_cascading_hash )
174
+ # remove local exclude
175
+ unless @local_cascading_hash.exclude_array.empty?
176
+ @local_cascading_hash.exclude_array.each do |this_excluded_element|
177
+ super_delete( this_excluded_element )
178
+ end
179
+ end
180
+ # notify children to update their composite status
181
+ update_sub_composite_arrays
182
+ return self
183
+ end
184
+
185
+ ######################################
186
+ # update_adding_composite_elements #
187
+ ######################################
188
+
189
+ def update_adding_composite_elements( elements_to_cascade )
190
+ update_composite_self_for_parent_hash( self, elements_to_cascade )
191
+ update_sub_composite_arrays
192
+ return self
193
+ end
194
+
195
+ ###########################################
196
+ # update_composite_self_for_parent_hash #
197
+ ###########################################
198
+
199
+ def update_composite_self_for_parent_hash( parent_hash, second_hash )
200
+
201
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( @configuration_instance )
202
+ for_instance = false
203
+
204
+ if ! module_configuration_support_module and ! is_a?( Module )
205
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( @configuration_instance.class )
206
+ for_instance = true
207
+ end
208
+
209
+ if compositing_proc = module_configuration_support_module.get_compositing_proc( @configuration_name, for_instance )
210
+ # if we have a compositing proc defined, use its result to replace
211
+ parent_hash_copy = Hash.new
212
+ parent_hash_copy.merge!( parent_hash ) if parent_hash
213
+ second_hash_copy = Hash.new
214
+ second_hash_copy.merge!( second_hash ) if second_hash
215
+ composite_result = compositing_proc.call( parent_hash_copy, second_hash_copy )
216
+ super_replace( composite_result )
217
+ else
218
+ # otherwise we simply merge
219
+ super_merge!( parent_hash ) if parent_hash
220
+ super_merge!( second_hash ) if second_hash
221
+ end
222
+ return self
223
+ end
224
+
225
+ ########################################
226
+ # update_removing_composite_elements #
227
+ ########################################
228
+
229
+ def update_removing_composite_elements( *elements_to_exclude )
230
+ elements_to_exclude.each do |this_key|
231
+ super_delete( this_key )
232
+ end
233
+ update_sub_composite_arrays
234
+ end
235
+
236
+ ###################################
237
+ # update_sub_composite_arrays #
238
+ ###################################
239
+
240
+ def update_sub_composite_arrays
241
+ @sub_composite_hashes.each do |this_composite_hash|
242
+ this_composite_hash.instance_eval { update_self_as_cascading_composite }
243
+ end
244
+ end
245
+
246
+ end