cascading_configuration 1.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.
Files changed (43) hide show
  1. data/CHANGELOG.md +40 -0
  2. data/README.md +211 -0
  3. data/lib/cascading_configuration/array/sorted/unique.rb +110 -0
  4. data/lib/cascading_configuration/array/sorted.rb +106 -0
  5. data/lib/cascading_configuration/array/unique.rb +106 -0
  6. data/lib/cascading_configuration/array.rb +103 -0
  7. data/lib/cascading_configuration/core/enable_instance_support.rb +22 -0
  8. data/lib/cascading_configuration/core/enable_module_support.rb +24 -0
  9. data/lib/cascading_configuration/core/encapsulation.rb +343 -0
  10. data/lib/cascading_configuration/core/instance_controller/extension_module.rb +38 -0
  11. data/lib/cascading_configuration/core/instance_controller/support_module/instance_support_module.rb +21 -0
  12. data/lib/cascading_configuration/core/instance_controller/support_module/singleton_support_module.rb +21 -0
  13. data/lib/cascading_configuration/core/instance_controller/support_module.rb +253 -0
  14. data/lib/cascading_configuration/core/instance_controller.rb +840 -0
  15. data/lib/cascading_configuration/core/module/block_configurations/cascading_variables.rb +129 -0
  16. data/lib/cascading_configuration/core/module/block_configurations.rb +15 -0
  17. data/lib/cascading_configuration/core/module/extended_configurations/compositing_objects.rb +173 -0
  18. data/lib/cascading_configuration/core/module/extended_configurations.rb +65 -0
  19. data/lib/cascading_configuration/core/module/inheriting_values.rb +64 -0
  20. data/lib/cascading_configuration/core/module.rb +284 -0
  21. data/lib/cascading_configuration/core.rb +23 -0
  22. data/lib/cascading_configuration/hash.rb +103 -0
  23. data/lib/cascading_configuration/setting.rb +87 -0
  24. data/lib/cascading_configuration.rb +47 -0
  25. data/lib/namespaces.rb +9 -0
  26. data/lib/requires.rb +46 -0
  27. data/spec/cascading_configuration/array/sorted/unique_spec.rb +742 -0
  28. data/spec/cascading_configuration/array/sorted_spec.rb +741 -0
  29. data/spec/cascading_configuration/array/unique_spec.rb +746 -0
  30. data/spec/cascading_configuration/array_spec.rb +768 -0
  31. data/spec/cascading_configuration/core/encapsulation_spec.rb +208 -0
  32. data/spec/cascading_configuration/core/instance_controller/extension_module_spec.rb +26 -0
  33. data/spec/cascading_configuration/core/instance_controller/support_module_spec.rb +269 -0
  34. data/spec/cascading_configuration/core/instance_controller_spec.rb +273 -0
  35. data/spec/cascading_configuration/core/module/block_configurations/cascading_variables_spec.rb +17 -0
  36. data/spec/cascading_configuration/core/module/extended_configurations/compositing_objects_spec.rb +127 -0
  37. data/spec/cascading_configuration/core/module/extended_configurations_spec.rb +37 -0
  38. data/spec/cascading_configuration/core/module/inheriting_values_spec.rb +87 -0
  39. data/spec/cascading_configuration/core/module_spec.rb +491 -0
  40. data/spec/cascading_configuration/hash_spec.rb +826 -0
  41. data/spec/cascading_configuration/setting_spec.rb +687 -0
  42. data/spec/cascading_configuration_spec.rb +58 -0
  43. metadata +185 -0
@@ -0,0 +1,22 @@
1
+
2
+ module ::CascadingConfiguration::Core::EnableInstanceSupport
3
+
4
+ ##############
5
+ # included #
6
+ ##############
7
+
8
+ def included( instance )
9
+
10
+ super if defined?( super )
11
+
12
+ # Ensure our instance has an instance controller
13
+ unless instance_controller = ::CascadingConfiguration::Core::InstanceController.instance_controller( instance )
14
+ default_encapsulation = self::ClassInstance.default_encapsulation
15
+ instance_controller = ::CascadingConfiguration::Core::InstanceController.new( instance, default_encapsulation )
16
+ end
17
+
18
+ instance_controller.create_instance_support
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,24 @@
1
+
2
+ module ::CascadingConfiguration::Core::EnableModuleSupport
3
+
4
+ ##############
5
+ # extended #
6
+ ##############
7
+
8
+ def extended( instance )
9
+
10
+ super if defined?( super )
11
+
12
+ # Ensure our instance has an instance controller
13
+ unless instance_controller = ::CascadingConfiguration::Core::InstanceController.instance_controller( instance )
14
+ instance_controller = ::CascadingConfiguration::Core::InstanceController.new( instance,
15
+ @default_encapsulation,
16
+ :Controller,
17
+ true )
18
+ end
19
+
20
+ instance_controller.create_singleton_support
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,343 @@
1
+
2
+ class ::CascadingConfiguration::Core::Encapsulation < ::Module
3
+
4
+ include ::ParallelAncestry
5
+
6
+ InstanceStruct = ::Struct.new( :configuration_variables_hash,
7
+ :configurations_hash,
8
+ :parent_for_configuration_hash )
9
+
10
+ @encapsulations = { }
11
+
12
+ ########################
13
+ # self.encapsulation #
14
+ ########################
15
+
16
+ def self.encapsulation( encapsulation_or_name, ensure_exists = false )
17
+
18
+ encapsulation_instance = nil
19
+
20
+ case encapsulation_or_name
21
+
22
+ when nil
23
+
24
+ encapsulation_instance = ::CascadingConfiguration::Core::Module::DefaultEncapsulation
25
+
26
+ when self
27
+
28
+ encapsulation_instance = encapsulation_or_name
29
+
30
+ when ::Symbol, ::String
31
+
32
+ unless encapsulation_instance = @encapsulations[ encapsulation_or_name ]
33
+ if ensure_exists
34
+ exception_string = 'No encapsulation defined for :' << encapsulation_or_name.to_s
35
+ exception_string << '.'
36
+ raise ::ArgumentError, exception_string
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ return encapsulation_instance
43
+
44
+ end
45
+
46
+ ################
47
+ # initialize #
48
+ ################
49
+
50
+ def initialize( encapsulation_name )
51
+
52
+ super()
53
+
54
+ @encapsulation_name = encapsulation_name
55
+
56
+ encapsulation_instance = self
57
+
58
+ # We manage reference to self in singleton from here to avoid duplicative efforts.
59
+ self.class.class_eval do
60
+ @encapsulations[ encapsulation_name ] = encapsulation_instance
61
+ const_set( encapsulation_name.to_s.to_camel_case, encapsulation_instance )
62
+ end
63
+
64
+ @instances_hash = { }
65
+
66
+ end
67
+
68
+ ########################
69
+ # encapsulation_name #
70
+ ########################
71
+
72
+ attr_reader :encapsulation_name
73
+
74
+ #########################
75
+ # has_configurations? #
76
+ #########################
77
+
78
+ def has_configurations?( instance )
79
+
80
+ return ! configurations( instance ).empty?
81
+
82
+ end
83
+
84
+ #########################
85
+ # configuration_names #
86
+ #########################
87
+
88
+ def configuration_names( instance )
89
+
90
+ return configurations( instance ).keys
91
+
92
+ end
93
+
94
+ ############################
95
+ # register_configuration #
96
+ ############################
97
+
98
+ def register_configuration( instance, configuration_name, configuration_module )
99
+
100
+ # Record that a configuration is defined for this instance.
101
+ #
102
+ # This doesn't suggest that a configuration exists for this instance and name, only that it has
103
+ # been registered to acknowledge it could exist.
104
+ return configurations( instance )[ configuration_name ] = configuration_module
105
+
106
+ end
107
+
108
+ ####################
109
+ # configurations #
110
+ ####################
111
+
112
+ def configurations( instance )
113
+
114
+ return configuration_struct( instance ).configurations_hash ||= { }
115
+
116
+ end
117
+
118
+ ########################
119
+ # has_configuration? #
120
+ ########################
121
+
122
+ def has_configuration?( instance, configuration_name )
123
+
124
+ has_configuration = nil
125
+
126
+ unless has_configuration = configurations( instance ).has_key?( configuration_name ) or
127
+ instance == instance.class
128
+ has_configuration = configurations( instance.class ).has_key?( configuration_name )
129
+ end
130
+
131
+ return has_configuration
132
+
133
+ end
134
+
135
+ ##########################
136
+ # remove_configuration #
137
+ ##########################
138
+
139
+ def remove_configuration( instance, configuration_name )
140
+
141
+ return configurations( instance ).delete( configuration_name )
142
+
143
+ end
144
+
145
+ ###############################
146
+ # register_child_for_parent #
147
+ ###############################
148
+
149
+ def register_child_for_parent( child, parent )
150
+
151
+ super
152
+
153
+ # Modules already have configurations and if parent already has configurations
154
+ unless parent.is_a?( ::Module ) or has_parents?( parent )
155
+ register_child_for_parent( parent, parent.class )
156
+ end
157
+
158
+ parent_configurations = configurations( parent )
159
+
160
+ parent_configurations.each do |this_name, this_configuration_module|
161
+ register_configuration( child, this_name, this_configuration_module )
162
+ register_parent_for_configuration( child, parent, this_name )
163
+ this_configuration_module.create_configuration( self, child, this_name )
164
+ end
165
+
166
+ parent_configurations.each do |this_name, this_configuration_module|
167
+ this_configuration_module.initialize_configuration( self, child, this_name )
168
+ end
169
+
170
+ end
171
+
172
+ ##################################
173
+ # is_parent_for_configuration? #
174
+ ##################################
175
+
176
+ def is_parent_for_configuration?( existing_parent, configuration_name, parent )
177
+
178
+ is_parent_for_configuration = false
179
+
180
+ this_parent = existing_parent
181
+
182
+ begin
183
+
184
+ if this_parent.equal?( parent )
185
+ is_parent_for_configuration = true
186
+ end
187
+
188
+ end while this_parent = parent_for_configuration( this_parent, configuration_name )
189
+
190
+ return is_parent_for_configuration
191
+
192
+ end
193
+
194
+ #######################################
195
+ # register_parent_for_configuration #
196
+ #######################################
197
+
198
+ def register_parent_for_configuration( child, parent, configuration_name )
199
+
200
+ parents_hash = parent_for_configuration_hash( child )
201
+
202
+ # if we already have a parent, check to see if new parent is an ancestor of it
203
+ # if so, keep existing parent
204
+ unless existing_parent = parents_hash[ configuration_name ] and
205
+ is_parent_for_configuration?( existing_parent, configuration_name, parent )
206
+
207
+ parents_hash[ configuration_name ] = parent
208
+
209
+ parents( child ).unshift( parent )
210
+
211
+ end
212
+
213
+ return self
214
+
215
+ end
216
+
217
+ ##############################
218
+ # parent_for_configuration #
219
+ ##############################
220
+
221
+ def parent_for_configuration( instance, configuration_name )
222
+
223
+ unless instance.equal?( ::Class ) or
224
+ parent = parent_for_configuration_hash( instance )[ configuration_name ]
225
+
226
+ instance_class = instance.class
227
+ if has_configuration?( instance_class, configuration_name )
228
+ parent = instance_class
229
+ end
230
+ end
231
+
232
+ return parent
233
+
234
+ end
235
+
236
+ #############################
237
+ # configuration_variables #
238
+ #############################
239
+
240
+ def configuration_variables( instance )
241
+
242
+ return configuration_struct( instance ).configuration_variables_hash ||= { }
243
+
244
+ end
245
+
246
+ #######################
247
+ # set_configuration #
248
+ #######################
249
+
250
+ def set_configuration( instance, configuration_name, value )
251
+
252
+ return configuration_variables( instance )[ configuration_name ] = value
253
+
254
+ end
255
+
256
+ ##############################
257
+ # has_configuration_value? #
258
+ ##############################
259
+
260
+ def has_configuration_value?( instance, configuration_name )
261
+
262
+ return configuration_variables( instance ).has_key?( configuration_name )
263
+
264
+ end
265
+
266
+ #######################
267
+ # get_configuration #
268
+ #######################
269
+
270
+ def get_configuration( instance, configuration_name )
271
+
272
+ return configuration_variables( instance )[ configuration_name ]
273
+
274
+ end
275
+
276
+ ###################################
277
+ # remove_configuration_variable #
278
+ ###################################
279
+
280
+ def remove_configuration_variable( instance, configuration_name )
281
+
282
+ return configuration_variables( instance ).delete( configuration_name )
283
+
284
+ end
285
+
286
+ ##################
287
+ # match_parent #
288
+ ##################
289
+
290
+ def match_parent( instance, configuration_name, & match_block )
291
+
292
+ matched_parent = nil
293
+
294
+ this_parent = instance
295
+
296
+ begin
297
+
298
+ if match_block.call( this_parent )
299
+ matched_parent = this_parent
300
+ break
301
+ end
302
+
303
+ end while this_parent = parent_for_configuration( this_parent, configuration_name )
304
+
305
+ return matched_parent
306
+
307
+ end
308
+
309
+ ##################################################################################################
310
+ private ######################################################################################
311
+ ##################################################################################################
312
+
313
+ ##########################
314
+ # configuration_struct #
315
+ ##########################
316
+
317
+ def configuration_struct( instance )
318
+
319
+ configuration_struct = nil
320
+
321
+ instance_id = instance.__id__
322
+
323
+ unless configuration_struct = @instances_hash[ instance_id ]
324
+ # fill in slots lazily
325
+ configuration_struct = self.class::InstanceStruct.new
326
+ @instances_hash[ instance_id ] = configuration_struct
327
+ end
328
+
329
+ return configuration_struct
330
+
331
+ end
332
+
333
+ ###################################
334
+ # parent_for_configuration_hash #
335
+ ###################################
336
+
337
+ def parent_for_configuration_hash( instance )
338
+
339
+ return configuration_struct( instance ).parent_for_configuration_hash ||= { }
340
+
341
+ end
342
+
343
+ end
@@ -0,0 +1,38 @@
1
+
2
+ class ::CascadingConfiguration::Core::InstanceController::ExtensionModule < ::Module
3
+
4
+ ################
5
+ # initialize #
6
+ ################
7
+
8
+ def initialize( instance_controller, encapsulation, configuration_name, & definer_block )
9
+
10
+ @instance_controller = instance_controller
11
+ @encapsulation = encapsulation
12
+ @configuration_name = configuration_name
13
+
14
+ if block_given?
15
+ module_eval( & definer_block )
16
+ end
17
+
18
+ end
19
+
20
+ #########################
21
+ # instance_controller #
22
+ #########################
23
+
24
+ attr_reader :instance_controller
25
+
26
+ ###################
27
+ # encapsulation #
28
+ ###################
29
+
30
+ attr_reader :encapsulation
31
+
32
+ ########################
33
+ # configuration_name #
34
+ ########################
35
+
36
+ attr_reader :configuration_name
37
+
38
+ end
@@ -0,0 +1,21 @@
1
+
2
+ class ::CascadingConfiguration::Core::InstanceController::SupportModule::InstanceSupportModule <
3
+ ::CascadingConfiguration::Core::InstanceController::SupportModule
4
+
5
+ ######################
6
+ # is_super_module? #
7
+ ######################
8
+
9
+ def is_super_module?( module_instance )
10
+
11
+ is_super_module = false
12
+
13
+ if is_super_module = super
14
+ is_super_module = module_instance.included?( @instance_controller.instance )
15
+ end
16
+
17
+ return is_super_module
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,21 @@
1
+
2
+ class ::CascadingConfiguration::Core::InstanceController::SupportModule::SingletonSupportModule <
3
+ ::CascadingConfiguration::Core::InstanceController::SupportModule
4
+
5
+ ######################
6
+ # is_super_module? #
7
+ ######################
8
+
9
+ def is_super_module?( module_instance )
10
+
11
+ is_super_module = false
12
+
13
+ if is_super_module = super
14
+ is_super_module = module_instance.extended?( @instance_controller.instance )
15
+ end
16
+
17
+ return is_super_module
18
+
19
+ end
20
+
21
+ end