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,284 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module < ::Module
3
+
4
+ DefaultEncapsulationName = :default
5
+ DefaultEncapsulation = ::CascadingConfiguration::Core::Encapsulation.new( DefaultEncapsulationName )
6
+
7
+ include ::CascadingConfiguration::Core::EnableModuleSupport
8
+
9
+ ################
10
+ # initialize #
11
+ ################
12
+
13
+ def initialize( ccm_name,
14
+ default_encapsulation_or_name = ::CascadingConfiguration::Core::Module::DefaultEncapsulation,
15
+ *ccm_aliases )
16
+
17
+ super()
18
+
19
+ encapsulation = ::CascadingConfiguration::Core::Encapsulation.encapsulation( default_encapsulation_or_name )
20
+
21
+ @default_encapsulation = encapsulation
22
+
23
+ @ccm_name = ccm_name
24
+ @ccm_aliases = ccm_aliases
25
+
26
+ define_definition_methods( @ccm_name, *@ccm_aliases )
27
+
28
+ end
29
+
30
+ ###########################
31
+ # default_encapsulation #
32
+ ###########################
33
+
34
+ attr_reader :default_encapsulation
35
+
36
+ ##############
37
+ # ccm_name #
38
+ ##############
39
+
40
+ attr_reader :ccm_name
41
+
42
+ #################
43
+ # ccm_aliases #
44
+ #################
45
+
46
+ attr_reader :ccm_aliases
47
+
48
+ ###############################
49
+ # define_definition_methods #
50
+ ###############################
51
+
52
+ def define_definition_methods( ccm_name, *ccm_aliases )
53
+
54
+ define_cascading_definition_method( ccm_name, *ccm_aliases )
55
+ define_module_definition_method( ccm_name, *ccm_aliases )
56
+ define_instance_definition_method( ccm_name, *ccm_aliases )
57
+ define_object_definition_method( ccm_name, *ccm_aliases )
58
+ define_local_instance_definition_method( ccm_name, *ccm_aliases )
59
+
60
+ end
61
+
62
+ ########################################
63
+ # define_cascading_definition_method #
64
+ ########################################
65
+
66
+ def define_cascading_definition_method( ccm_name, *ccm_aliases )
67
+
68
+ ccm_method_name = cascading_method_name( ccm_name )
69
+ ccm_alias_names = ccm_aliases.collect { |this_alias| cascading_method_name( this_alias ) }
70
+
71
+ return define_method_with_extension_modules( ccm_method_name, ccm_alias_names, :all )
72
+
73
+ end
74
+
75
+ #####################################
76
+ # define_module_definition_method #
77
+ #####################################
78
+
79
+ def define_module_definition_method( ccm_name, *ccm_aliases )
80
+
81
+ ccm_method_name = module_method_name( ccm_name )
82
+ ccm_alias_names = [ class_method_name( ccm_name ) ]
83
+ ccm_alias_names.concat( ccm_aliases.collect { |this_alias| module_method_name( this_alias ) } )
84
+ ccm_alias_names.concat( ccm_aliases.collect { |this_alias| class_method_name( this_alias ) } )
85
+
86
+ return define_method_with_extension_modules( ccm_method_name, ccm_alias_names, :module )
87
+
88
+ end
89
+
90
+ #######################################
91
+ # define_instance_definition_method #
92
+ #######################################
93
+
94
+ def define_instance_definition_method( ccm_name, *ccm_aliases )
95
+
96
+ ccm_method_name = instance_method_name( ccm_name )
97
+ ccm_alias_names = ccm_aliases.collect { |this_alias| instance_method_name( this_alias ) }
98
+
99
+ return define_method_with_extension_modules( ccm_method_name, ccm_alias_names, :instance )
100
+
101
+ end
102
+
103
+ #############################################
104
+ # define_local_instance_definition_method #
105
+ #############################################
106
+
107
+ def define_local_instance_definition_method( ccm_name, *ccm_aliases )
108
+
109
+ ccm_method_name = local_instance_method_name( ccm_name )
110
+ ccm_alias_names = ccm_aliases.collect { |this_alias| local_instance_method_name( this_alias ) }
111
+
112
+ return define_method_with_extension_modules( ccm_method_name, ccm_alias_names, :local_instance )
113
+
114
+ end
115
+
116
+ #####################################
117
+ # define_object_definition_method #
118
+ #####################################
119
+
120
+ def define_object_definition_method( ccm_name, *ccm_aliases )
121
+
122
+ ccm_method_name = object_method_name( ccm_name )
123
+ ccm_alias_names = ccm_aliases.collect { |this_alias| object_method_name( this_alias ) }
124
+
125
+ return define_method_with_extension_modules( ccm_method_name, ccm_alias_names, :object )
126
+
127
+ end
128
+
129
+ ##########################
130
+ # create_configuration #
131
+ ##########################
132
+
133
+ def create_configuration( encapsulation, instance, name )
134
+
135
+ encapsulation.register_configuration( instance, name, self )
136
+
137
+ return self
138
+
139
+ end
140
+
141
+ ##############################
142
+ # initialize_configuration #
143
+ ##############################
144
+
145
+ def initialize_configuration( encapsulation, instance, name )
146
+
147
+ # Nothing here - for subclasses to define.
148
+
149
+ end
150
+
151
+ ###########################
152
+ # define_configurations #
153
+ ###########################
154
+
155
+ def define_configurations( instance_controller, encapsulation, method_types, *names, & definer_block )
156
+
157
+ accessors = instance_controller.define_configuration_methods( self, encapsulation, method_types, names, & definer_block )
158
+
159
+ instance = instance_controller.instance
160
+
161
+ accessors.each do |this_accessor, this_write_accessor|
162
+ create_configuration( encapsulation, instance, this_accessor )
163
+ end
164
+
165
+ end
166
+
167
+ ##################################################################################################
168
+ private ######################################################################################
169
+ ##################################################################################################
170
+
171
+ ###########################
172
+ # cascading_method_name #
173
+ ###########################
174
+
175
+ def cascading_method_name( base_name )
176
+
177
+ return 'attr_' << base_name.to_s
178
+
179
+ end
180
+
181
+ ########################
182
+ # module_method_name #
183
+ ########################
184
+
185
+ def module_method_name( base_name )
186
+
187
+ return 'attr_module_' << base_name.to_s
188
+
189
+ end
190
+
191
+ #######################
192
+ # class_method_name #
193
+ #######################
194
+
195
+ def class_method_name( base_name )
196
+
197
+ return 'attr_class_' << base_name.to_s
198
+
199
+ end
200
+
201
+ ##########################
202
+ # instance_method_name #
203
+ ##########################
204
+
205
+ def instance_method_name( base_name )
206
+
207
+ return 'attr_instance_' << base_name.to_s
208
+
209
+ end
210
+
211
+ ################################
212
+ # local_instance_method_name #
213
+ ################################
214
+
215
+ def local_instance_method_name( base_name )
216
+
217
+ return 'attr_local_' << base_name.to_s
218
+
219
+ end
220
+
221
+ ########################
222
+ # object_method_name #
223
+ ########################
224
+
225
+ def object_method_name( base_name )
226
+
227
+ return 'attr_object_' << base_name.to_s
228
+
229
+ end
230
+
231
+ ##########################################
232
+ # define_method_with_extension_modules #
233
+ ##########################################
234
+
235
+ def define_method_with_extension_modules( ccm_method_name, ccm_aliases, *method_types )
236
+
237
+ # Methods that define configurations that optionally take modules as parameters as well as a
238
+ # block that will be used to dynamically define an extension module for the instances created
239
+ # by the configurations.
240
+ #
241
+ # This defines attr_... :configuration_name, ModuleInstance, ... { ... }
242
+
243
+ ccm = self
244
+
245
+ #======================#
246
+ # ccm_method_name_in #
247
+ #======================#
248
+
249
+ ccm_encapsulation_method_name = ccm_method_name.to_s + '_in'
250
+
251
+ define_method( ccm_encapsulation_method_name ) do |encapsulation_or_name, *args, & definer_block|
252
+
253
+ encapsulation = ::CascadingConfiguration::Core::Encapsulation.encapsulation( encapsulation_or_name, true )
254
+
255
+ instance_controller = ::CascadingConfiguration::Core::InstanceController.instance_controller( self, true )
256
+
257
+ ccm.define_configurations( instance_controller, encapsulation, method_types, *args, & definer_block )
258
+
259
+ return self
260
+
261
+ end
262
+
263
+ #===================#
264
+ # ccm_method_name #
265
+ #===================#
266
+
267
+ default_encapsulation = @default_encapsulation_name
268
+
269
+ define_method( ccm_method_name ) do |*args, & definer_block|
270
+
271
+ return __send__( ccm_encapsulation_method_name, default_encapsulation, *args, & definer_block )
272
+
273
+ end
274
+
275
+ ccm_aliases.each do |this_alias|
276
+ alias_method( this_alias.to_s + '_in', ccm_encapsulation_method_name )
277
+ alias_method( this_alias, ccm_method_name )
278
+ end
279
+
280
+ return self
281
+
282
+ end
283
+
284
+ end
@@ -0,0 +1,23 @@
1
+
2
+ # @private
3
+ module ::CascadingConfiguration::Core
4
+
5
+ #################
6
+ # self.enable #
7
+ #################
8
+
9
+ # @private
10
+ def self.enable( instance, ccm )
11
+
12
+ instance.const_set( :ClassInstance, ccm )
13
+
14
+ # Enable module instance so that when included it creates instance support
15
+ instance.extend( ::CascadingConfiguration::Core::EnableInstanceSupport )
16
+
17
+ instance.extend( ::ModuleCluster )
18
+
19
+ instance.include_or_extend_also_extends( instance::ClassInstance )
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,103 @@
1
+
2
+ ###
3
+ # CascadingConfiguration::Hash allows definition of hash attributes that will composite downward through
4
+ # the ancestor chain.
5
+ #
6
+ module ::CascadingConfiguration::Hash
7
+
8
+ ###
9
+ # Cascading hash attribute methods, which will affect instances according to include/extend pattern used.
10
+ #
11
+ # @method attr_hash
12
+ #
13
+ # @overload attr_hash( *names )
14
+ #
15
+ # @scope
16
+ #
17
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String},Module] name The name to be used
18
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
19
+ # name and accessor and each value will be used as the corresponding write accessor.
20
+ #
21
+ # @yield [ ] Creates a new Module of type CascadingConfiguration::Core::InstanceController::ExtensionModule
22
+ # and runs module_eval( & block ) on instance with provided block.
23
+ #
24
+ # @return self
25
+ #
26
+
27
+ ###
28
+ # Cascading hash attribute module/class methods, which will affect all module singletons
29
+ # according to include/extend pattern used.
30
+ #
31
+ # @method attr_module_hash
32
+ #
33
+ # @overload attr_module_hash( *names )
34
+ #
35
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String}] name The name to be used
36
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
37
+ # name and accessor and each value will be used as the corresponding write accessor.
38
+ #
39
+ # @yield [ ] Creates a new Module of type CascadingConfiguration::Core::InstanceController::ExtensionModule
40
+ # and runs module_eval( & block ) on instance with provided block.
41
+ #
42
+ # @return self
43
+ #
44
+
45
+ ###
46
+ # Cascading hash instance methods, which will affect instances of including modules according to
47
+ # include/extend pattern used.
48
+ #
49
+ # @method attr_instance_hash
50
+ #
51
+ # @overload attr_instance_hash( *names )
52
+ #
53
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String}] name The name to be used
54
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
55
+ # name and accessor and each value will be used as the corresponding write accessor.
56
+ #
57
+ # @yield [ ] Creates a new Module of type CascadingConfiguration::Core::InstanceController::ExtensionModule
58
+ # and runs module_eval( & block ) on instance with provided block.
59
+ #
60
+ # @return self
61
+ #
62
+
63
+ ###
64
+ # Non-cascading hash methods that will affect the instance declared on as well as instances of that instance,
65
+ # if applicable.
66
+ #
67
+ # @method attr_local_hash
68
+ #
69
+ # @overload attr_local_hash( *names )
70
+ #
71
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String}] name The name to be used
72
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
73
+ # name and accessor and each value will be used as the corresponding write accessor.
74
+ #
75
+ # @yield [ ] Creates a new Module of type CascadingConfiguration::Core::InstanceController::ExtensionModule
76
+ # and runs module_eval( & block ) on instance with provided block.
77
+ #
78
+ # @return self
79
+ #
80
+
81
+ ###
82
+ # Non-cascading hash methods that will affect only the instance declared on.
83
+ #
84
+ # @method attr_object_hash
85
+ #
86
+ # @overload attr_object_hash( *names )
87
+ #
88
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String}] name The name to be used
89
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
90
+ # name and accessor and each value will be used as the corresponding write accessor.
91
+ #
92
+ # @yield [ ] Creates a new Module of type CascadingConfiguration::Core::InstanceController::ExtensionModule
93
+ # and runs module_eval( & block ) on instance with provided block.
94
+ #
95
+ # @return self
96
+ #
97
+
98
+ hash_module = ::CascadingConfiguration::Core::Module::ExtendedConfigurations::
99
+ CompositingObjects.new( :hash, ::CompositingHash, :default, :configuration_hash )
100
+
101
+ ::CascadingConfiguration::Core.enable( self, hash_module )
102
+
103
+ end
@@ -0,0 +1,87 @@
1
+
2
+ ###
3
+ # CascadingConfiguration::Setting allows definition of setting attributes that will retrieve
4
+ # the first value defined in an instance looking up the ancestor chain.
5
+ #
6
+ module ::CascadingConfiguration::Setting
7
+
8
+ ###
9
+ # Cascading setting attribute methods, which will affect instances according to include/extend pattern used.
10
+ #
11
+ # @method attr_setting
12
+ #
13
+ # @overload attr_setting( *names )
14
+ #
15
+ # @scope
16
+ #
17
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String}] name The name to be used
18
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
19
+ # name and accessor and each value will be used as the corresponding write accessor.
20
+ #
21
+ # @return self
22
+ #
23
+
24
+ ###
25
+ # Cascading setting attribute module/class methods, which will affect all module singletons
26
+ # according to include/extend pattern used.
27
+ #
28
+ # @method attr_module_setting
29
+ #
30
+ # @overload attr_module_setting( *names )
31
+ #
32
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String}] name The name to be used
33
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
34
+ # name and accessor and each value will be used as the corresponding write accessor.
35
+ #
36
+ # @return self
37
+ #
38
+
39
+ ###
40
+ # Cascading setting instance methods, which will affect instances of including modules according to
41
+ # include/extend pattern used.
42
+ #
43
+ # @method attr_instance_setting
44
+ #
45
+ # @overload attr_instance_setting( *names )
46
+ #
47
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String}] name The name to be used
48
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
49
+ # name and accessor and each value will be used as the corresponding write accessor.
50
+ #
51
+ # @return self
52
+ #
53
+
54
+ ###
55
+ # Non-cascading setting methods that will affect the instance declared on as well as instances of that instance,
56
+ # if applicable.
57
+ #
58
+ # @method attr_local_setting
59
+ #
60
+ # @overload attr_local_setting( *names )
61
+ #
62
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String}] name The name to be used
63
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
64
+ # name and accessor and each value will be used as the corresponding write accessor.
65
+ #
66
+ # @return self
67
+ #
68
+
69
+ ###
70
+ # Non-cascading setting methods that will affect only the instance declared on.
71
+ #
72
+ # @method attr_object_setting
73
+ #
74
+ # @overload attr_object_setting( *names )
75
+ #
76
+ # @param [Symbol,String,Hash{Symbol,String=>Symbol,String}] name The name to be used
77
+ # for the declared attribute. If a hash is passed, each key will be used as the setting
78
+ # name and accessor and each value will be used as the corresponding write accessor.
79
+ #
80
+ # @return self
81
+ #
82
+
83
+ setting_module = ::CascadingConfiguration::Core::Module::InheritingValues.new( :setting, :default, :configuration )
84
+
85
+ ::CascadingConfiguration::Core.enable( self, setting_module )
86
+
87
+ end
@@ -0,0 +1,47 @@
1
+
2
+ # namespaces that have to be declared ahead of time for proper load order
3
+ require_relative './namespaces'
4
+
5
+ # source file requires
6
+ require_relative './requires.rb'
7
+
8
+ module ::CascadingConfiguration
9
+
10
+ ConfigurationModules = [ Setting,
11
+ Hash,
12
+ Array,
13
+ Array::Unique,
14
+ Array::Sorted,
15
+ Array::Sorted::Unique ]
16
+
17
+ ###################
18
+ # self.included #
19
+ ###################
20
+
21
+ def self.included( instance )
22
+
23
+ super if defined?( super )
24
+
25
+ instance.module_eval do
26
+ ::CascadingConfiguration::ConfigurationModules.each do |this_member|
27
+ include( this_member )
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ ###################
34
+ # self.extended #
35
+ ###################
36
+
37
+ def self.extended( instance )
38
+
39
+ super if defined?( super )
40
+
41
+ ::CascadingConfiguration::ConfigurationModules.each do |this_member|
42
+ instance.extend( this_member )
43
+ end
44
+
45
+ end
46
+
47
+ end
data/lib/namespaces.rb ADDED
@@ -0,0 +1,9 @@
1
+
2
+ module ::CascadingConfiguration
3
+ module Core
4
+ class InstanceController < ::Module
5
+ module Methods
6
+ end
7
+ end
8
+ end
9
+ end
data/lib/requires.rb ADDED
@@ -0,0 +1,46 @@
1
+ require 'to_camel_case'
2
+ require 'accessor-utilities'
3
+ require 'parallel-ancestry'
4
+ require 'compositing-hash'
5
+ require 'compositing-array-sorted-unique'
6
+
7
+ #require_relative '../../compositing_objects/compositing-hash/lib/compositing-hash.rb'
8
+
9
+ basepath = 'cascading_configuration'
10
+
11
+ files = [
12
+
13
+ 'core/enable_module_support',
14
+ 'core/enable_instance_support',
15
+
16
+ 'core',
17
+
18
+ 'core/encapsulation',
19
+
20
+ 'core/module',
21
+ 'core/module/inheriting_values',
22
+ 'core/module/extended_configurations',
23
+ 'core/module/extended_configurations/compositing_objects',
24
+ 'core/module/block_configurations',
25
+ 'core/module/block_configurations/cascading_variables',
26
+
27
+ 'core/instance_controller/support_module',
28
+ 'core/instance_controller/support_module/instance_support_module',
29
+ 'core/instance_controller/support_module/singleton_support_module',
30
+ 'core/instance_controller/extension_module',
31
+ 'core/instance_controller',
32
+
33
+ 'setting',
34
+
35
+ 'hash',
36
+
37
+ 'array',
38
+ 'array/unique',
39
+ 'array/sorted',
40
+ 'array/sorted/unique'
41
+
42
+ ]
43
+
44
+ files.each do |this_file|
45
+ require_relative( File.join( basepath, this_file ) + '.rb' )
46
+ end