cascading_configuration 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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