cascading-configuration-hash 1.6.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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