cascading-configuration-hash 1.6.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,13 @@
1
1
 
2
- require 'cascading-configuration-variable'
3
- #require_relative '../../variable/lib/cascading-configuration-variable.rb'
2
+ if $__cascading_configuration__spec__development
3
+ require_relative '../../variable/lib/cascading-configuration-variable.rb'
4
+ else
5
+ require 'cascading-configuration-variable'
6
+ end
4
7
 
5
8
  module CascadingConfiguration
6
9
  module Hash
7
10
  class CompositingHash < ::Hash
8
- class LocalConfigurationHash < ::Hash
9
- end
10
11
  end
11
12
  module Interface
12
13
  module GettersSetters
@@ -15,7 +16,6 @@ module CascadingConfiguration
15
16
  end
16
17
  end
17
18
 
18
- require_relative 'cascading-configuration-hash/_private_/CascadingConfiguration/Hash/CompositingHash/LocalConfigurationHash.rb'
19
19
  require_relative 'cascading-configuration-hash/_private_/CascadingConfiguration/Hash/CompositingHash.rb'
20
20
  require_relative 'cascading-configuration-hash/_private_/CascadingConfiguration/Hash/Interface/GettersSetters.rb'
21
21
  require_relative 'cascading-configuration-hash/_private_/CascadingConfiguration/Hash/ModuleSupportMethods.rb'
@@ -8,15 +8,15 @@ module CascadingConfiguration::Hash::Interface
8
8
  # attr_configuration_hash #
9
9
  #############################
10
10
 
11
- # defines configuration in class or module
12
- # configuration cascades downward to instance including all classes or modules in-between
11
+ # defines configuration in class or module
12
+ # configuration cascades downward to instance including all classes or modules in-between
13
13
  def attr_configuration_hash( *configuration_names, & compositing_block )
14
14
 
15
15
  configuration_names.each do |this_configuration_name|
16
16
  if block_given?
17
- ::CascadingConfiguration::Variable.set_compositing_proc( self,
18
- this_configuration_name,
19
- compositing_block )
17
+ ::CascadingConfiguration::Variable.set_compositing_proc( self,
18
+ this_configuration_name,
19
+ compositing_block )
20
20
  end
21
21
  # define configuration setter
22
22
  define_cascading_hash_setter( this_configuration_name )
@@ -32,15 +32,15 @@ module CascadingConfiguration::Hash::Interface
32
32
  # attr_module_configuration_hash #
33
33
  ####################################
34
34
 
35
- # defines configuration in class or module
36
- # configuration cascades downward to last class or module
35
+ # defines configuration in class or module
36
+ # configuration cascades downward to last class or module
37
37
  def attr_module_configuration_hash( *configuration_names, & compositing_block )
38
38
 
39
39
  configuration_names.each do |this_configuration_name|
40
40
  if block_given?
41
- ::CascadingConfiguration::Variable.set_compositing_proc( self,
42
- this_configuration_name,
43
- compositing_block )
41
+ ::CascadingConfiguration::Variable.set_compositing_proc( self,
42
+ this_configuration_name,
43
+ compositing_block )
44
44
  end
45
45
  # define configuration setter
46
46
  define_class_configuration_hash_setter( this_configuration_name )
@@ -51,23 +51,23 @@ module CascadingConfiguration::Hash::Interface
51
51
  return self
52
52
 
53
53
  end
54
- alias_method :attr_class_configuration_hash, :attr_module_configuration_hash
54
+ alias_method :attr_class_configuration_hash, :attr_module_configuration_hash
55
55
 
56
56
  ###################################
57
57
  # attr_local_configuration_hash #
58
58
  ###################################
59
59
 
60
- # defines configuration in present class or module context
61
- # configuration does not cascade
60
+ # defines configuration in present class or module context
61
+ # configuration does not cascade
62
62
  def attr_local_configuration_hash( *configuration_names, & compositing_block )
63
63
 
64
- ::CascadingConfiguration::Variable.create_local_instance_configuration_support_module( self )
64
+ ::CascadingConfiguration::Variable.create_local_instance_configuration_support_module( self )
65
65
 
66
66
  configuration_names.each do |this_configuration_name|
67
67
  if block_given?
68
- ::CascadingConfiguration::Variable.set_compositing_proc( self,
69
- this_configuration_name,
70
- compositing_block )
68
+ ::CascadingConfiguration::Variable.set_compositing_proc( self,
69
+ this_configuration_name,
70
+ compositing_block )
71
71
  end
72
72
  # define configuration setter
73
73
  define_local_configuration_hash_setter( this_configuration_name )
@@ -83,17 +83,17 @@ module CascadingConfiguration::Hash::Interface
83
83
  # attr_object_configuration_hash #
84
84
  ####################################
85
85
 
86
- # defines configuration in present class or module context
87
- # configuration does not cascade
86
+ # defines configuration in present class or module context
87
+ # configuration does not cascade
88
88
  def attr_object_configuration_hash( *configuration_names, & compositing_block )
89
89
 
90
- ::CascadingConfiguration::Variable.create_local_instance_configuration_support_module( self )
90
+ ::CascadingConfiguration::Variable.create_local_instance_configuration_support_module( self )
91
91
 
92
92
  configuration_names.each do |this_configuration_name|
93
93
  if block_given?
94
- ::CascadingConfiguration::Variable.set_compositing_proc( self,
95
- this_configuration_name,
96
- compositing_block )
94
+ ::CascadingConfiguration::Variable.set_compositing_proc( self,
95
+ this_configuration_name,
96
+ compositing_block )
97
97
  end
98
98
  # define configuration setter
99
99
  define_object_configuration_hash_setter( this_configuration_name )
@@ -109,15 +109,15 @@ module CascadingConfiguration::Hash::Interface
109
109
  # attr_instance_configuration_hash #
110
110
  ######################################
111
111
 
112
- # defines configuration in present class or module context
113
- # configuration does not cascade
112
+ # defines configuration in present class or module context
113
+ # configuration does not cascade
114
114
  def attr_instance_configuration_hash( *configuration_names, & compositing_block )
115
115
 
116
116
  configuration_names.each do |this_configuration_name|
117
117
  if block_given?
118
- ::CascadingConfiguration::Variable.set_compositing_proc( self,
119
- this_configuration_name,
120
- compositing_block )
118
+ ::CascadingConfiguration::Variable.set_compositing_proc( self,
119
+ this_configuration_name,
120
+ compositing_block )
121
121
  end
122
122
  # define configuration setter
123
123
  define_instance_configuration_hash_setter( this_configuration_name )
@@ -1,7 +1,5 @@
1
1
 
2
- class CascadingConfiguration::Hash::CompositingHash < ::Hash
3
-
4
- attr_accessor :local_cascading_hash
2
+ class ::CascadingConfiguration::Hash::CompositingHash < ::Hash
5
3
 
6
4
  ################
7
5
  # initialize #
@@ -9,45 +7,55 @@ class CascadingConfiguration::Hash::CompositingHash < ::Hash
9
7
 
10
8
  def initialize( configuration_instance, configuration_name )
11
9
 
12
- @configuration_instance = configuration_instance
13
-
10
+ @configuration_instance = configuration_instance
14
11
  @configuration_name = configuration_name
15
12
 
13
+ @replaced_parents = {}
14
+
16
15
  # store self for sub composites
17
- ::CascadingConfiguration::Variable.set_configuration_variable( configuration_instance, configuration_name, self )
16
+ ::CascadingConfiguration::Variable.set_configuration_variable( configuration_instance,
17
+ configuration_name,
18
+ self )
19
+
20
+ # get compositing proc if we have one
21
+ @compositing_proc = ::CascadingConfiguration::Variable.
22
+ get_compositing_proc_searching_upward( configuration_instance, @configuration_name )
23
+
24
+ # we may later have our own child composites that register with us
25
+ @sub_composite_hashes = [ ]
18
26
 
19
- # if first ancestor can have a composite hash, register self with it in case it gets updated in the future
20
- if ancestor = ::CascadingConfiguration::Variable.ancestor( configuration_instance, configuration_name )
27
+ # if first ancestor can have a composite hash,
28
+ # register self with it in case it gets updated in the future
29
+ if ancestor = ::CascadingConfiguration::Variable.ancestor( configuration_instance,
30
+ configuration_name )
21
31
 
22
- @super_composite_hash = ::CascadingConfiguration::Variable.get_configuration_variable( ancestor,
23
- configuration_name )
32
+ @super_composite_hash = ::CascadingConfiguration::Variable.
33
+ get_configuration_variable( ancestor,
34
+ configuration_name )
24
35
 
25
36
  if @super_composite_hash.respond_to?( :register_sub_composite_hash )
26
37
  @super_composite_hash.register_sub_composite_hash( self )
38
+ merge!( @super_composite_hash )
27
39
  else
28
40
  @super_composite_hash = nil
29
41
  end
30
42
 
31
43
  end
32
44
 
33
- # instantiate local cascading hash
34
- @local_cascading_hash = ::CascadingConfiguration::Hash::CompositingHash::LocalConfigurationHash.new
35
-
36
- # we may later have our own child composites that register with us
37
- @sub_composite_hashes = [ ]
38
-
39
- # initialize self status for parent and local
40
- update_self_as_cascading_composite
41
-
42
45
  end
43
46
 
47
+ ################################### Sub-Hash Management #######################################
48
+
44
49
  #################################
45
50
  # register_sub_composite_hash #
46
51
  #################################
47
52
 
48
53
  def register_sub_composite_hash( sub_composite_hash )
54
+
49
55
  @sub_composite_hashes.push( sub_composite_hash )
56
+
50
57
  return self
58
+
51
59
  end
52
60
 
53
61
  ###################################
@@ -55,17 +63,37 @@ class CascadingConfiguration::Hash::CompositingHash < ::Hash
55
63
  ###################################
56
64
 
57
65
  def unregister_sub_composite_hash( sub_composite_hash )
66
+
58
67
  @sub_composite_hashes.delete( sub_composite_hash )
68
+
59
69
  return self
70
+
60
71
  end
61
72
 
73
+ ##################################### Self Management ##########################################
74
+
62
75
  #########
63
76
  # []= #
64
77
  #########
65
78
 
66
- def []=( key, value )
67
- @local_cascading_hash[ key ] = value
68
- update_adding_composite_elements( key => value )
79
+ private
80
+ alias_method :non_cascading_store, :store
81
+ public
82
+
83
+ def []=( key, object )
84
+
85
+ @replaced_parents[ key ] = true
86
+
87
+ non_cascading_store( key, object )
88
+
89
+ @sub_composite_hashes.each do |this_sub_hash|
90
+ this_sub_hash.instance_eval do
91
+ update_as_sub_hash_for_parent_store( key, object )
92
+ end
93
+ end
94
+
95
+ return object
96
+
69
97
  end
70
98
  alias_method :store, :[]=
71
99
 
@@ -73,37 +101,147 @@ class CascadingConfiguration::Hash::CompositingHash < ::Hash
73
101
  # delete #
74
102
  ############
75
103
 
76
- alias_method :super_delete, :delete
104
+ private
105
+ alias_method :non_cascading_delete, :delete
106
+ public
107
+
77
108
  def delete( key )
78
- value = self[ key ]
79
- @local_cascading_hash.delete( key )
80
- update_removing_composite_elements( key )
81
- return value
109
+
110
+ @replaced_parents.delete( key )
111
+
112
+ object = non_cascading_delete( key )
113
+
114
+ @sub_composite_hashes.each do |this_sub_hash|
115
+ this_sub_hash.instance_eval do
116
+ update_as_sub_hash_for_parent_delete( key )
117
+ end
118
+ end
119
+
120
+ return object
121
+
122
+ end
123
+
124
+ ###############
125
+ # delete_if #
126
+ ###############
127
+
128
+ def delete_if
129
+
130
+ return to_enum unless block_given?
131
+
132
+ indexes = [ ]
133
+
134
+ self.each do |this_key, this_object|
135
+ if yield( this_key, this_object )
136
+ delete( this_key )
137
+ end
138
+ end
139
+
140
+ return self
141
+
142
+ end
143
+
144
+ #############
145
+ # reject! #
146
+ #############
147
+
148
+ def reject!
149
+
150
+ return to_enum unless block_given?
151
+
152
+ return_value = nil
153
+
154
+ self.each do |this_key, this_object|
155
+ if yield( this_key, this_object )
156
+ delete( this_key )
157
+ return_value = self
158
+ end
159
+ end
160
+
161
+ return return_value
162
+
163
+ end
164
+
165
+ #############
166
+ # keep_if #
167
+ #############
168
+
169
+ def keep_if
170
+
171
+ return to_enum unless block_given?
172
+
173
+ indexes = [ ]
174
+
175
+ self.each do |this_key, this_object|
176
+ unless yield( this_key, this_object )
177
+ delete( this_key )
178
+ end
179
+ end
180
+
181
+ return self
182
+
183
+
184
+ end
185
+
186
+ #############
187
+ # select! #
188
+ #############
189
+
190
+ def select!
191
+
192
+ return to_enum unless block_given?
193
+
194
+ return_value = nil
195
+
196
+ self.each do |this_key, this_object|
197
+ unless yield( this_key, this_object )
198
+ delete( this_key )
199
+ return_value = self
200
+ end
201
+ end
202
+
203
+ return return_value
204
+
82
205
  end
83
206
 
84
207
  ############
85
208
  # merge! #
209
+ # update #
86
210
  ############
87
211
 
88
- alias_method :super_merge!, :merge!
212
+ private
213
+ alias_method :non_cascading_merge!, :merge!
214
+ public
215
+
89
216
  def merge!( other_hash )
90
- @local_cascading_hash.merge!( other_hash )
91
- update_adding_composite_elements( other_hash )
217
+
218
+ other_hash.each do |this_key, this_object|
219
+ if @compositing_proc
220
+ self[ this_key ] = @compositing_proc.call( self, this_key, this_object )
221
+ else
222
+ self[ this_key ] = this_object
223
+ end
224
+ end
225
+
92
226
  return self
227
+
93
228
  end
229
+ alias_method :update, :merge!
94
230
 
95
231
  #############
96
232
  # replace #
97
233
  #############
98
234
 
99
- alias_method :super_replace, :replace
100
235
  def replace( other_hash )
236
+
101
237
  # clear current values
102
238
  clear
239
+
103
240
  # merge replacement settings
104
241
  merge!( other_hash )
105
- update_self_as_cascading_composite
242
+
106
243
  return self
244
+
107
245
  end
108
246
 
109
247
  ###########
@@ -111,25 +249,30 @@ class CascadingConfiguration::Hash::CompositingHash < ::Hash
111
249
  ###########
112
250
 
113
251
  def shift
114
- element = super
115
- key = element[ 0 ]
116
- @local_cascading_hash.delete( key )
117
- update_removing_composite_elements( key )
118
- return element
252
+
253
+ object = nil
254
+
255
+ unless empty?
256
+ last_key = first[ 0 ]
257
+ object = delete( last_key )
258
+ end
259
+
260
+ return [ last_key, object ]
261
+
119
262
  end
120
263
 
121
264
  ###########
122
265
  # clear #
123
266
  ###########
124
267
 
125
- alias_method :super_clear, :clear
126
268
  def clear
127
- # add all existing values to exclude array
269
+
128
270
  keys.each do |this_key|
129
271
  delete( this_key )
130
272
  end
131
- update_removing_composite_elements( *self.keys )
273
+
132
274
  return self
275
+
133
276
  end
134
277
 
135
278
  #############
@@ -139,90 +282,59 @@ class CascadingConfiguration::Hash::CompositingHash < ::Hash
139
282
  # freezes configuration and prevents ancestors from changing this configuration in the future
140
283
  def freeze!
141
284
 
142
- # move current configuration into local configuration
143
- @local_cascading_hash.replace( self )
144
-
145
285
  # unregister with parent composite so we don't get future updates from it
146
- @super_composite_hash.unregister_sub_composite_hash( self ) if @super_composite_hash
286
+ if @super_composite_hash
287
+ @super_composite_hash.unregister_sub_composite_hash( self )
288
+ end
147
289
 
148
290
  return self
149
291
 
150
292
  end
151
293
 
152
- ###########################################################################################################
153
- private ###############################################################################################
154
- ###########################################################################################################
294
+ ##################################################################################################
295
+ private ######################################################################################
296
+ ##################################################################################################
155
297
 
156
- ########################################
157
- # update_self_as_cascading_composite #
158
- ########################################
298
+ ######################### Self-as-Sub Management for Parent Updates ############################
159
299
 
160
- def update_self_as_cascading_composite
161
- # start fresh
162
- super_clear
163
- update_composite_self_for_parent_hash( @super_composite_hash, @local_cascading_hash )
164
- # remove local exclude
165
- unless @local_cascading_hash.exclude_array.empty?
166
- @local_cascading_hash.exclude_array.each do |this_excluded_element|
167
- super_delete( this_excluded_element )
300
+ #########################################
301
+ # update_as_sub_hash_for_parent_store #
302
+ #########################################
303
+
304
+ def update_as_sub_hash_for_parent_store( key, object )
305
+
306
+ unless @replaced_parents[ key ]
307
+
308
+ non_cascading_store( key, object )
309
+
310
+ @sub_composite_hashes.each do |this_hash|
311
+ this_hash.instance_eval do
312
+ update_as_sub_hash_for_parent_store( key, object )
313
+ end
168
314
  end
315
+
169
316
  end
170
- # notify children to update their composite status
171
- update_sub_composite_arrays
172
- return self
173
- end
174
-
175
- ######################################
176
- # update_adding_composite_elements #
177
- ######################################
178
-
179
- def update_adding_composite_elements( elements_to_cascade )
180
- update_composite_self_for_parent_hash( self, elements_to_cascade )
181
- update_sub_composite_arrays
182
- return self
183
- end
184
-
185
- ###########################################
186
- # update_composite_self_for_parent_hash #
187
- ###########################################
188
-
189
- def update_composite_self_for_parent_hash( parent_hash, second_hash )
190
-
191
- if compositing_proc = ::CascadingConfiguration::Variable.get_compositing_proc_searching_upward( @configuration_instance, @configuration_name )
192
- # if we have a compositing proc defined, use its result to replace
193
- parent_hash_copy = { }
194
- parent_hash_copy.merge!( parent_hash ) if parent_hash
195
- second_hash_copy = { }
196
- second_hash_copy.merge!( second_hash ) if second_hash
197
- composite_result = compositing_proc.call( parent_hash_copy, second_hash_copy )
198
- super_replace( composite_result )
199
- else
200
- # otherwise we simply merge
201
- super_merge!( parent_hash ) if parent_hash
202
- super_merge!( second_hash ) if second_hash
203
- end
204
- return self
205
- end
206
-
207
- ########################################
208
- # update_removing_composite_elements #
209
- ########################################
210
-
211
- def update_removing_composite_elements( *elements_to_exclude )
212
- elements_to_exclude.each do |this_key|
213
- super_delete( this_key )
214
- end
215
- update_sub_composite_arrays
317
+
216
318
  end
217
319
 
218
- ###################################
219
- # update_sub_composite_arrays #
220
- ###################################
221
-
222
- def update_sub_composite_arrays
223
- @sub_composite_hashes.each do |this_composite_hash|
224
- this_composite_hash.instance_eval { update_self_as_cascading_composite }
320
+ ##########################################
321
+ # update_as_sub_hash_for_parent_delete #
322
+ ##########################################
323
+
324
+ def update_as_sub_hash_for_parent_delete( key )
325
+
326
+ unless @replaced_parents[ key ]
327
+
328
+ non_cascading_delete( key )
329
+
330
+ @sub_composite_hashes.each do |this_hash|
331
+ this_hash.instance_eval do
332
+ update_as_sub_hash_for_parent_delete( key )
333
+ end
334
+ end
335
+
225
336
  end
337
+
226
338
  end
227
339
 
228
340
  end