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,129 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::BlockConfigurations::CascadingVariables <
3
+ ::CascadingConfiguration::Core::Module::BlockConfigurations
4
+
5
+ ##########################
6
+ # create_configuration #
7
+ ##########################
8
+
9
+ # Pending.
10
+ def create_configuration( encapsulation, instance, name )
11
+
12
+ unless compositing_object = encapsulation.get_configuration( instance, name )
13
+
14
+ super
15
+
16
+ # initialize without initializing for parents
17
+ # we will initialize for parents after initializing all instances for inheritance
18
+ compositing_object = @compositing_object_class.new( nil, instance )
19
+
20
+ instance_controller = ::CascadingConfiguration::Core::InstanceController.nearest_instance_controller( encapsulation,
21
+ instance,
22
+ name )
23
+
24
+ extension_modules = instance_controller.extension_modules_upward( name, encapsulation )
25
+
26
+ unless extension_modules.empty?
27
+ # Modules are gathered from lowest ancestor upward. This means that they are already
28
+ # in the proper order for include/extend (which usually we would have to reverse).
29
+ compositing_object.extend( *extension_modules )
30
+ end
31
+
32
+ encapsulation.set_configuration( instance, name, compositing_object )
33
+
34
+ initialize_compositing_configuration_for_parent( encapsulation, instance, name )
35
+
36
+ end
37
+
38
+ return compositing_object
39
+
40
+ end
41
+
42
+ ############
43
+ # setter #
44
+ ############
45
+
46
+ # Pending.
47
+ def setter( encapsulation, instance, name, value )
48
+
49
+ return encapsulation.set_configuration( instance, name, value )
50
+
51
+ end
52
+
53
+ ############
54
+ # getter #
55
+ ############
56
+
57
+ # Pending.
58
+ def getter( encapsulation, instance, name )
59
+
60
+ return encapsulation.get_configuration( instance, name )
61
+
62
+ end
63
+
64
+ #####################
65
+ # instance_setter #
66
+ #####################
67
+
68
+ # Pending.
69
+ def instance_setter( encapsulation, instance, name, value )
70
+
71
+ # ensure our compositing object already exists
72
+ instance_getter( encapsulation, instance, name, value )
73
+
74
+ # now we can set normally
75
+ return setter( encapsulation, instance, name, value )
76
+
77
+ end
78
+
79
+ #####################
80
+ # instance_getter #
81
+ #####################
82
+
83
+ # Pending.
84
+ def instance_getter( encapsulation, instance, name )
85
+
86
+ cascading_value = nil
87
+
88
+ if encapsulation.has_configuration_value?( instance, name )
89
+ cascading_value = encapsulation.get_configuration( instance, name )
90
+ else
91
+ cascading_value = initialize_configuration_for_parent( encapsulation, instance, configuration_name )
92
+ end
93
+
94
+ return cascading_value
95
+
96
+ end
97
+
98
+ #####################################################
99
+ # initialize_compositing_configuration_for_parent #
100
+ #####################################################
101
+
102
+ # Pending.
103
+ def initialize_compositing_configuration_for_parent( encapsulation, instance, configuration_name )
104
+
105
+ unless compositing_object = encapsulation.get_configuration( instance, configuration_name )
106
+ compositing_object = create_configuration( encapsulation, instance, configuration_name )
107
+ end
108
+
109
+ # if instance has a parent
110
+ if parent = encapsulation.parent_for_configuration( instance, configuration_name )
111
+
112
+ # if first parent for configuration isn't initialized yet, initialize it
113
+ unless parent_composite_object = encapsulation.get_configuration( parent, configuration_name )
114
+ parent_composite_object = initialize_compositing_configuration_for_parent( encapsulation,
115
+ parent,
116
+ configuration_name )
117
+ end
118
+
119
+ unless compositing_object.parent_composite_object == parent_composite_object
120
+ compositing_object.initialize_for_parent( parent_composite_object )
121
+ end
122
+
123
+ end
124
+
125
+ return compositing_object
126
+
127
+ end
128
+
129
+ end
@@ -0,0 +1,15 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::BlockConfigurations < ::CascadingConfiguration::Core::Module
3
+
4
+ ###########################
5
+ # define_configurations #
6
+ ###########################
7
+
8
+ # Pending.
9
+ def define_configurations( instance_controller, encapsulation, method_types, *names, & definer_block )
10
+
11
+ super
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,173 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::ExtendedConfigurations::CompositingObjects <
3
+ ::CascadingConfiguration::Core::Module::ExtendedConfigurations
4
+
5
+ ################
6
+ # initialize #
7
+ ################
8
+
9
+ def initialize( ccm_name,
10
+ compositing_object_class = nil,
11
+ default_encapsulation_or_encapsulation_name = ::CascadingConfiguration::Core::
12
+ Module::DefaultEncapsulation,
13
+ *ccm_aliases )
14
+
15
+ super( ccm_name, default_encapsulation_or_encapsulation_name, *ccm_aliases )
16
+
17
+ @compositing_object_class = compositing_object_class
18
+
19
+ end
20
+
21
+ ##########################
22
+ # create_configuration #
23
+ ##########################
24
+
25
+ def create_configuration( encapsulation, instance, name )
26
+
27
+ unless compositing_object = encapsulation.get_configuration( instance, name )
28
+
29
+ super
30
+
31
+ # initialize without initializing for parents
32
+ # we will initialize for parents after initializing all instances for inheritance
33
+ compositing_object = @compositing_object_class.new( nil, instance )
34
+
35
+ instance_controller = ::CascadingConfiguration::Core::
36
+ InstanceController.nearest_instance_controller( encapsulation, instance, name )
37
+
38
+ if instance_controller
39
+
40
+ extension_modules = instance_controller.extension_modules_upward( name, encapsulation )
41
+
42
+ unless extension_modules.empty?
43
+ # Modules are gathered from lowest ancestor upward. This means that they are already
44
+ # in the proper order for include/extend (which usually we would have to reverse).
45
+ compositing_object.extend( *extension_modules )
46
+ end
47
+
48
+ end
49
+
50
+ encapsulation.set_configuration( instance, name, compositing_object )
51
+
52
+ end
53
+
54
+ return compositing_object
55
+
56
+ end
57
+
58
+ ##############################
59
+ # initialize_configuration #
60
+ ##############################
61
+
62
+ def initialize_configuration( encapsulation, instance, name )
63
+
64
+ initialize_compositing_configuration_for_parent( encapsulation, instance, name )
65
+
66
+ end
67
+
68
+ ##############################
69
+ # compositing_object_class #
70
+ ##############################
71
+
72
+ attr_reader :compositing_object_class
73
+
74
+ ############
75
+ # setter #
76
+ ############
77
+
78
+ def setter( encapsulation, instance, name, value )
79
+
80
+ compositing_object = encapsulation.get_configuration( instance, name )
81
+
82
+ compositing_object.replace( value )
83
+
84
+ return compositing_object
85
+
86
+ end
87
+
88
+ #####################
89
+ # instance_setter #
90
+ #####################
91
+
92
+ def instance_setter( encapsulation, instance, name, value )
93
+
94
+ # ensure our compositing object already exists
95
+ instance_getter( encapsulation, instance, name )
96
+
97
+ # now we can set normally
98
+ return setter( encapsulation, instance, name, value )
99
+
100
+ end
101
+
102
+ ############
103
+ # getter #
104
+ ############
105
+
106
+ def getter( encapsulation, instance, name )
107
+
108
+ return encapsulation.get_configuration( instance, name )
109
+
110
+ end
111
+
112
+ #####################
113
+ # instance_getter #
114
+ #####################
115
+
116
+ def instance_getter( encapsulation, instance, name )
117
+
118
+ compositing_object = nil
119
+
120
+ unless compositing_object = encapsulation.get_configuration( instance, name )
121
+ compositing_object = initialize_compositing_configuration_for_parent( encapsulation, instance, name )
122
+ end
123
+
124
+ return compositing_object
125
+
126
+ end
127
+
128
+ #####################################################
129
+ # initialize_compositing_configuration_for_parent #
130
+ #####################################################
131
+
132
+ def initialize_compositing_configuration_for_parent( encapsulation, instance, configuration_name )
133
+
134
+ unless compositing_object = encapsulation.get_configuration( instance, configuration_name )
135
+ compositing_object = create_configuration( encapsulation, instance, configuration_name )
136
+ end
137
+
138
+ # if instance has a parent
139
+ if parent = encapsulation.parent_for_configuration( instance, configuration_name )
140
+
141
+ # We are initializing for existing ancestors, but they may not have initialized yet -
142
+ # so we need to make sure they did before we initialize for instance.
143
+
144
+ # As long as our ancestor has an ancestor make sure that it has initialized for its parent.
145
+ # We can break at the first ancestor that we hit that has initialized for parent
146
+ # or if we run out of ancestors.
147
+
148
+ parent_composite_object = encapsulation.get_configuration( parent, configuration_name )
149
+ parent_composite_object2 = nil
150
+ if parent2 = encapsulation.parent_for_configuration( parent, configuration_name )
151
+ parent_composite_object2 = encapsulation.get_configuration( parent2, configuration_name )
152
+ end
153
+
154
+ # if first parent for configuration isn't initialized yet, initialize it
155
+ unless parent_composite_object and
156
+ parent_composite_object.parent_composite_object.equal?( parent_composite_object2 )
157
+
158
+ parent_composite_object = initialize_compositing_configuration_for_parent( encapsulation,
159
+ parent,
160
+ configuration_name )
161
+ end
162
+
163
+ unless compositing_object.parent_composite_object.equal?( parent_composite_object )
164
+ compositing_object.initialize_for_parent( parent_composite_object )
165
+ end
166
+
167
+ end
168
+
169
+ return compositing_object
170
+
171
+ end
172
+
173
+ end
@@ -0,0 +1,65 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::ExtendedConfigurations < ::CascadingConfiguration::Core::Module
3
+
4
+ ##################################
5
+ # self.parse_extension_modules #
6
+ ##################################
7
+
8
+ def self.parse_extension_modules( instance_controller, encapsulation, *names_modules )
9
+
10
+ # We can have configuration names or modules - we need to separate them.
11
+ names = [ ]
12
+ modules = [ ]
13
+
14
+ names_modules.each do |this_name_or_module|
15
+
16
+ case this_name_or_module
17
+
18
+ when ::Class
19
+
20
+ raise ArgumentError, 'Module expected (received Class).'
21
+
22
+ when ::Module
23
+
24
+ modules.push( this_name_or_module )
25
+
26
+ else
27
+
28
+ names.push( this_name_or_module )
29
+
30
+ end
31
+
32
+ end
33
+
34
+ names_modules_hash = { }
35
+
36
+ # if we have a block to define extensions to the compositing object:
37
+
38
+ names.each do |this_name|
39
+ names_modules_hash[ this_name ] = modules
40
+ end
41
+
42
+ return names_modules_hash
43
+
44
+ end
45
+
46
+ ###########################
47
+ # define_configurations #
48
+ ###########################
49
+
50
+ def define_configurations( instance_controller, encapsulation, method_types, *names_modules, & definer_block )
51
+
52
+ # Ask MethodModule to parse extension modules for these declarations on instance.
53
+ names_modules_hash = self.class.parse_extension_modules( instance_controller, encapsulation, *names_modules )
54
+
55
+ names_modules_hash.each do |this_name, these_modules|
56
+ instance_controller.add_extension_modules( this_name, encapsulation, *these_modules, & definer_block )
57
+ end
58
+
59
+ names = names_modules_hash.keys
60
+
61
+ super( instance_controller, encapsulation, method_types, *names, & definer_block )
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,64 @@
1
+
2
+ class ::CascadingConfiguration::Core::Module::InheritingValues < ::CascadingConfiguration::Core::Module
3
+
4
+ ############
5
+ # setter #
6
+ ############
7
+
8
+ def setter( encapsulation, instance, name, value )
9
+
10
+ return encapsulation.set_configuration( instance, name, value )
11
+
12
+ end
13
+
14
+ ############
15
+ # getter #
16
+ ############
17
+
18
+ def getter( encapsulation, instance, name )
19
+
20
+ return get_configuration_searching_upward( encapsulation, instance, name )
21
+
22
+ end
23
+
24
+ #####################
25
+ # instance_getter #
26
+ #####################
27
+
28
+ alias_method( :instance_getter, :getter )
29
+
30
+ #####################
31
+ # instance_setter #
32
+ #####################
33
+
34
+ alias_method( :instance_setter, :setter )
35
+
36
+ ########################################
37
+ # get_configuration_searching_upward #
38
+ ########################################
39
+
40
+ def get_configuration_searching_upward( encapsulation, instance, configuration_name )
41
+
42
+ configuration_value = nil
43
+
44
+ matching_ancestor = nil
45
+
46
+ did_match_ancestor = false
47
+
48
+ matching_ancestor = encapsulation.match_parent( instance, configuration_name ) do |this_ancestor|
49
+ if encapsulation.has_configuration_value?( this_ancestor, configuration_name )
50
+ did_match_ancestor = true
51
+ else
52
+ false
53
+ end
54
+ end
55
+
56
+ if did_match_ancestor
57
+ configuration_value = encapsulation.get_configuration( matching_ancestor, configuration_name )
58
+ end
59
+
60
+ return configuration_value
61
+
62
+ end
63
+
64
+ end