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.
- data/CHANGELOG.md +40 -0
- data/README.md +211 -0
- data/lib/cascading_configuration/array/sorted/unique.rb +110 -0
- data/lib/cascading_configuration/array/sorted.rb +106 -0
- data/lib/cascading_configuration/array/unique.rb +106 -0
- data/lib/cascading_configuration/array.rb +103 -0
- data/lib/cascading_configuration/core/enable_instance_support.rb +22 -0
- data/lib/cascading_configuration/core/enable_module_support.rb +24 -0
- data/lib/cascading_configuration/core/encapsulation.rb +343 -0
- data/lib/cascading_configuration/core/instance_controller/extension_module.rb +38 -0
- data/lib/cascading_configuration/core/instance_controller/support_module/instance_support_module.rb +21 -0
- data/lib/cascading_configuration/core/instance_controller/support_module/singleton_support_module.rb +21 -0
- data/lib/cascading_configuration/core/instance_controller/support_module.rb +253 -0
- data/lib/cascading_configuration/core/instance_controller.rb +840 -0
- data/lib/cascading_configuration/core/module/block_configurations/cascading_variables.rb +129 -0
- data/lib/cascading_configuration/core/module/block_configurations.rb +15 -0
- data/lib/cascading_configuration/core/module/extended_configurations/compositing_objects.rb +173 -0
- data/lib/cascading_configuration/core/module/extended_configurations.rb +65 -0
- data/lib/cascading_configuration/core/module/inheriting_values.rb +64 -0
- data/lib/cascading_configuration/core/module.rb +284 -0
- data/lib/cascading_configuration/core.rb +23 -0
- data/lib/cascading_configuration/hash.rb +103 -0
- data/lib/cascading_configuration/setting.rb +87 -0
- data/lib/cascading_configuration.rb +47 -0
- data/lib/namespaces.rb +9 -0
- data/lib/requires.rb +46 -0
- data/spec/cascading_configuration/array/sorted/unique_spec.rb +742 -0
- data/spec/cascading_configuration/array/sorted_spec.rb +741 -0
- data/spec/cascading_configuration/array/unique_spec.rb +746 -0
- data/spec/cascading_configuration/array_spec.rb +768 -0
- data/spec/cascading_configuration/core/encapsulation_spec.rb +208 -0
- data/spec/cascading_configuration/core/instance_controller/extension_module_spec.rb +26 -0
- data/spec/cascading_configuration/core/instance_controller/support_module_spec.rb +269 -0
- data/spec/cascading_configuration/core/instance_controller_spec.rb +273 -0
- data/spec/cascading_configuration/core/module/block_configurations/cascading_variables_spec.rb +17 -0
- data/spec/cascading_configuration/core/module/extended_configurations/compositing_objects_spec.rb +127 -0
- data/spec/cascading_configuration/core/module/extended_configurations_spec.rb +37 -0
- data/spec/cascading_configuration/core/module/inheriting_values_spec.rb +87 -0
- data/spec/cascading_configuration/core/module_spec.rb +491 -0
- data/spec/cascading_configuration/hash_spec.rb +826 -0
- data/spec/cascading_configuration/setting_spec.rb +687 -0
- data/spec/cascading_configuration_spec.rb +58 -0
- 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
|