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.
- data/lib/cascading-configuration-hash.rb +5 -5
- data/lib/cascading-configuration-hash/CascadingConfiguration/Hash/Interface.rb +28 -28
- data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/CompositingHash.rb +223 -111
- data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/Interface/GettersSetters.rb +16 -16
- data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/ModuleSupportMethods.rb +5 -5
- data/spec/CascadingConfiguration/Hash_spec.rb +17 -19
- data/spec/_private_/CascadingConfiguration/Hash/CompositingHash_spec.rb +266 -216
- metadata +6 -8
- data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/CompositingHash/LocalConfigurationHash.rb +0 -110
- data/spec/_private_/CascadingConfiguration/Hash/CompositingHash/LocalConfigurationHash_spec.rb +0 -95
@@ -1,12 +1,13 @@
|
|
1
1
|
|
2
|
-
|
3
|
-
|
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
|
-
|
12
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
36
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
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
|
-
|
61
|
-
|
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
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
87
|
-
|
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
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
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
|
-
|
113
|
-
|
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
|
-
|
119
|
-
|
120
|
-
|
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 )
|
data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/CompositingHash.rb
CHANGED
@@ -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,
|
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,
|
20
|
-
|
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.
|
23
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
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
|
-
|
104
|
+
private
|
105
|
+
alias_method :non_cascading_delete, :delete
|
106
|
+
public
|
107
|
+
|
77
108
|
def delete( key )
|
78
|
-
|
79
|
-
@
|
80
|
-
|
81
|
-
|
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
|
-
|
212
|
+
private
|
213
|
+
alias_method :non_cascading_merge!, :merge!
|
214
|
+
public
|
215
|
+
|
89
216
|
def merge!( other_hash )
|
90
|
-
|
91
|
-
|
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
|
-
|
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
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
269
|
+
|
128
270
|
keys.each do |this_key|
|
129
271
|
delete( this_key )
|
130
272
|
end
|
131
|
-
|
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
|
-
|
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
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
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
|
-
|
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
|
-
#
|
220
|
-
|
221
|
-
|
222
|
-
def
|
223
|
-
|
224
|
-
|
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
|