cascading-configuration-hash 1.4.1 → 1.5.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 (19) hide show
  1. data/lib/cascading-configuration-hash/CascadingConfiguration/Hash/Interface.rb +86 -27
  2. data/lib/cascading-configuration-hash/CascadingConfiguration/Hash.rb +5 -21
  3. data/lib/cascading-configuration-hash/{CascadingConfiguration → _private_/CascadingConfiguration/Hash/CompositingHash}/LocalConfigurationHash.rb +29 -2
  4. data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/CompositingHash.rb +246 -0
  5. data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/Interface/GettersSetters.rb +233 -0
  6. data/lib/cascading-configuration-hash/_private_/CascadingConfiguration/Hash/ModuleSupportMethods.rb +29 -0
  7. data/lib/cascading-configuration-hash.rb +12 -23
  8. data/spec/CascadingConfiguration/Hash_spec.rb +2 -3
  9. data/spec/{CascadingConfiguration → _private_/CascadingConfiguration/Hash/CompositingHash}/LocalConfigurationHash_spec.rb +9 -9
  10. data/spec/_private_/CascadingConfiguration/Hash/CompositingHash_spec.rb +347 -0
  11. metadata +10 -28
  12. data/lib/cascading-configuration-hash/CascadingConfiguration/CompositingHash/Instance.rb +0 -31
  13. data/lib/cascading-configuration-hash/CascadingConfiguration/CompositingHash.rb +0 -135
  14. data/lib/cascading-configuration-hash/CascadingConfiguration/Hash/AccessorDefinitionMethods.rb +0 -149
  15. data/lib/cascading-configuration-hash/CascadingConfiguration/Hash/Interface/Instance.rb +0 -26
  16. data/lib/cascading-configuration-hash/CascadingConfiguration/_private_/CompositingHash.rb +0 -79
  17. data/lib/cascading-configuration-hash/CascadingConfiguration/_private_/LocalConfigurationHash.rb +0 -31
  18. data/spec/CascadingConfiguration/CascadingCompositeHash_spec.rb +0 -416
  19. data/spec/CascadingConfiguration/Hash/AccessorDefinitionMethods_spec.rb +0 -30
@@ -1,7 +1,8 @@
1
1
 
2
2
  module CascadingConfiguration::Hash::Interface
3
3
 
4
- extend CascadingConfiguration::InternalModuleStub
4
+ # Support methods that define configuration settings hash methods
5
+ include ::CascadingConfiguration::Hash::Interface::GettersSetters
5
6
 
6
7
  #############################
7
8
  # attr_configuration_hash #
@@ -9,14 +10,22 @@ module CascadingConfiguration::Hash::Interface
9
10
 
10
11
  # defines configuration in class or module
11
12
  # configuration cascades downward to instance including all classes or modules in-between
12
- def attr_configuration_hash( *property_names, & compositing_block )
13
+ def attr_configuration_hash( *configuration_names, & compositing_block )
13
14
 
14
- property_names.each do |this_property_name|
15
- accessor_module_support.set_compositing_proc( this_property_name, compositing_block ) if block_given?
15
+ configuration_names.each do |this_configuration_name|
16
+ if block_given?
17
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
18
+ for_instance = false
19
+ if ! is_a?( Module ) and ! module_configuration_support_module
20
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
21
+ for_instance = true
22
+ end
23
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
24
+ end
16
25
  # define configuration setter
17
- define_cascading_hash_setter( this_property_name )
26
+ define_cascading_hash_setter( this_configuration_name )
18
27
  # define configuration getter
19
- define_cascading_hash_getter( this_property_name )
28
+ define_cascading_hash_getter( this_configuration_name )
20
29
  end
21
30
 
22
31
  return self
@@ -29,14 +38,22 @@ module CascadingConfiguration::Hash::Interface
29
38
 
30
39
  # defines configuration in class or module
31
40
  # configuration cascades downward to last class or module
32
- def attr_module_configuration_hash( *property_names, & compositing_block )
41
+ def attr_module_configuration_hash( *configuration_names, & compositing_block )
33
42
 
34
- property_names.each do |this_property_name|
35
- accessor_module_support.set_compositing_proc( this_property_name, compositing_block ) if block_given?
43
+ configuration_names.each do |this_configuration_name|
44
+ if block_given?
45
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
46
+ for_instance = false
47
+ if ! is_a?( Module ) and ! module_configuration_support_module
48
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
49
+ for_instance = true
50
+ end
51
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
52
+ end
36
53
  # define configuration setter
37
- define_class_configuration_hash_setter( this_property_name )
54
+ define_class_configuration_hash_setter( this_configuration_name )
38
55
  # define configuration getter
39
- define_class_configuration_hash_getter( this_property_name )
56
+ define_class_configuration_hash_getter( this_configuration_name )
40
57
  end
41
58
 
42
59
  return self
@@ -50,19 +67,25 @@ module CascadingConfiguration::Hash::Interface
50
67
 
51
68
  # defines configuration in present class or module context
52
69
  # configuration does not cascade
53
- def attr_local_configuration_hash( *property_names, & compositing_block )
54
-
55
- CascadingConfiguration::Variable.define_accessor_local_instance_support( self )
56
-
57
- property_names.each do |this_property_name|
58
- accessor_module_support.set_compositing_proc( this_property_name, compositing_block ) if block_given?
70
+ def attr_local_configuration_hash( *configuration_names, & compositing_block )
71
+
72
+ CascadingConfiguration::Variable.initialize_local_instance_configuration_module( self )
73
+
74
+ configuration_names.each do |this_configuration_name|
75
+ if block_given?
76
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
77
+ for_instance = false
78
+ if ! is_a?( Module ) and ! module_configuration_support_module
79
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
80
+ for_instance = true
81
+ end
82
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
83
+ end
59
84
  # define configuration setter
60
- define_local_configuration_hash_setter( this_property_name )
85
+ define_local_configuration_hash_setter( this_configuration_name )
61
86
  # define configuration getter
62
- define_local_configuration_hash_getter( this_property_name )
87
+ define_local_configuration_hash_getter( this_configuration_name )
63
88
  end
64
-
65
- CascadingConfiguration::Variable.cascade_local_instance( self )
66
89
 
67
90
  return self
68
91
 
@@ -74,16 +97,52 @@ module CascadingConfiguration::Hash::Interface
74
97
 
75
98
  # defines configuration in present class or module context
76
99
  # configuration does not cascade
77
- def attr_object_configuration_hash( *property_names, & compositing_block )
100
+ def attr_object_configuration_hash( *configuration_names, & compositing_block )
101
+
102
+ CascadingConfiguration::Variable.initialize_local_instance_configuration_module( self )
103
+
104
+ configuration_names.each do |this_configuration_name|
105
+ if block_given?
106
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
107
+ for_instance = false
108
+ if ! is_a?( Module ) and ! module_configuration_support_module
109
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
110
+ for_instance = true
111
+ end
112
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
113
+ end
114
+ # define configuration setter
115
+ define_object_configuration_hash_setter( this_configuration_name )
116
+ # define configuration getter
117
+ define_object_configuration_hash_getter( this_configuration_name )
118
+ end
119
+
120
+ return self
121
+
122
+ end
78
123
 
79
- CascadingConfiguration::Variable.define_accessor_local_instance_support( self )
124
+ ######################################
125
+ # attr_instance_configuration_hash #
126
+ ######################################
80
127
 
81
- property_names.each do |this_property_name|
82
- accessor_module_support.set_compositing_proc( this_property_name, compositing_block ) if block_given?
128
+ # defines configuration in present class or module context
129
+ # configuration does not cascade
130
+ def attr_instance_configuration_hash( *configuration_names, & compositing_block )
131
+
132
+ configuration_names.each do |this_configuration_name|
133
+ if block_given?
134
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self )
135
+ for_instance = false
136
+ if ! is_a?( Module ) and ! module_configuration_support_module
137
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( self.class )
138
+ for_instance = true
139
+ end
140
+ module_configuration_support_module.set_compositing_proc( this_configuration_name, compositing_block, for_instance )
141
+ end
83
142
  # define configuration setter
84
- define_object_configuration_hash_setter( this_property_name )
143
+ define_instance_configuration_hash_setter( this_configuration_name )
85
144
  # define configuration getter
86
- define_object_configuration_hash_getter( this_property_name )
145
+ define_instance_configuration_hash_getter( this_configuration_name )
87
146
  end
88
147
 
89
148
  return self
@@ -1,28 +1,12 @@
1
1
 
2
2
  module CascadingConfiguration::Hash
3
3
 
4
- extend ModuleCluster
5
-
6
- extend CascadingConfiguration::InternalModuleStub
7
-
8
- include CascadingConfiguration::Variable
9
-
10
- include CascadingConfiguration::CompositingHash::Instance
11
- include CascadingConfiguration::Hash::Interface
12
- include CascadingConfiguration::Hash::AccessorDefinitionMethods
4
+ # Configuration modules for storage of settings hashes
5
+ include ::CascadingConfiguration::Variable
13
6
 
14
- prepend_module_include do |class_or_module|
15
- class_or_module.extend_also_extends( CascadingConfiguration::Variable::EigenclassConfigurationChain )
16
- end
7
+ # Interface to declare configuration settings hashes
8
+ include ::CascadingConfiguration::Hash::Interface
17
9
 
18
- include_cascades_extends( CascadingConfiguration::Hash::Interface::Instance )
19
-
20
- include_cascades_extends( CascadingConfiguration::Hash )
10
+ extend ::CascadingConfiguration::Hash::ModuleSupportMethods
21
11
 
22
- prepend_module_include do |class_or_module|
23
- class_or_module.include_or_extend_cascades_prepending_extends do
24
- accessor_module_support
25
- end
26
- end
27
-
28
12
  end
@@ -1,6 +1,6 @@
1
1
 
2
- class CascadingConfiguration::LocalConfigurationHash < Hash
3
-
2
+ class CascadingConfiguration::Hash::CompositingHash::LocalConfigurationHash < Hash
3
+
4
4
  attr_accessor :exclude_array
5
5
 
6
6
  ################
@@ -80,4 +80,31 @@ class CascadingConfiguration::LocalConfigurationHash < Hash
80
80
  super
81
81
  end
82
82
 
83
+ ###########################################################################################################
84
+ private ###############################################################################################
85
+ ###########################################################################################################
86
+
87
+ ##########################
88
+ # add_to_exclude_array #
89
+ ##########################
90
+
91
+ def add_to_exclude_array( *elements )
92
+ @exclude_array ||= ::Array.new
93
+ @exclude_array += elements
94
+ @exclude_array.sort!.uniq!
95
+ end
96
+
97
+ ###############################
98
+ # remove_from_exclude_array #
99
+ ###############################
100
+
101
+ def remove_from_exclude_array( *elements )
102
+ if @exclude_array
103
+ @exclude_array -= elements
104
+ @exclude_array.sort!.uniq!
105
+ else
106
+ @exclude_array ||= ::Array.new
107
+ end
108
+ end
109
+
83
110
  end
@@ -0,0 +1,246 @@
1
+
2
+ class CascadingConfiguration::Hash::CompositingHash < Hash
3
+
4
+ attr_accessor :local_cascading_hash
5
+
6
+ ################
7
+ # initialize #
8
+ ################
9
+
10
+ def initialize( configuration_instance, configuration_name )
11
+
12
+ for_instance = false
13
+
14
+ @configuration_instance = configuration_instance
15
+
16
+ module_configuration_module = ::CascadingConfiguration::Variable.module_configuration_support_module( configuration_instance )
17
+ if ! module_configuration_module and ! configuration_instance.is_a?( Module )
18
+ module_configuration_module = ::CascadingConfiguration::Variable.module_configuration_support_module( configuration_instance.class )
19
+ for_instance = true
20
+ end
21
+
22
+ @configuration_name = configuration_name
23
+
24
+ # store self for sub composites
25
+ module_configuration_module.set_configuration_variable( configuration_name, self, for_instance )
26
+
27
+ # if first ancestor can have a composite hash, register self with it in case it gets updated in the future
28
+ super_configuration_module = nil
29
+ if for_instance
30
+ super_configuration_module = module_configuration_module
31
+ else
32
+ super_configuration_module = module_configuration_module.super_configuration_module
33
+ end
34
+
35
+ if super_configuration_module and
36
+ @super_composite_hash = super_configuration_module.get_configuration_variable( configuration_name ) and
37
+ @super_composite_hash.respond_to?( :register_sub_composite_hash )
38
+
39
+ @super_composite_hash.register_sub_composite_hash( self )
40
+
41
+ end
42
+
43
+ # instantiate local cascading hash
44
+ @local_cascading_hash = ::CascadingConfiguration::Hash::CompositingHash::LocalConfigurationHash.new
45
+
46
+ # we may later have our own child composites that register with us
47
+ @sub_composite_hashes = ::Array.new
48
+
49
+ # initialize self status for parent and local
50
+ update_self_as_cascading_composite
51
+
52
+ end
53
+
54
+ #################################
55
+ # register_sub_composite_hash #
56
+ #################################
57
+
58
+ def register_sub_composite_hash( sub_composite_hash )
59
+ @sub_composite_hashes.push( sub_composite_hash )
60
+ return self
61
+ end
62
+
63
+ ###################################
64
+ # unregister_sub_composite_hash #
65
+ ###################################
66
+
67
+ def unregister_sub_composite_hash( sub_composite_hash )
68
+ @sub_composite_hashes.delete( sub_composite_hash )
69
+ return self
70
+ end
71
+
72
+ #########
73
+ # []= #
74
+ #########
75
+
76
+ def []=( key, value )
77
+ @local_cascading_hash[ key ] = value
78
+ update_adding_composite_elements( key => value )
79
+ end
80
+ alias_method :store, :[]=
81
+
82
+ ############
83
+ # delete #
84
+ ############
85
+
86
+ alias_method :super_delete, :delete
87
+ def delete( key )
88
+ value = self[ key ]
89
+ @local_cascading_hash.delete( key )
90
+ update_removing_composite_elements( key )
91
+ return value
92
+ end
93
+
94
+ ############
95
+ # merge! #
96
+ ############
97
+
98
+ alias_method :super_merge!, :merge!
99
+ def merge!( other_hash )
100
+ @local_cascading_hash.merge!( other_hash )
101
+ update_adding_composite_elements( other_hash )
102
+ return self
103
+ end
104
+
105
+ #############
106
+ # replace #
107
+ #############
108
+
109
+ alias_method :super_replace, :replace
110
+ def replace( other_hash )
111
+ # clear current values
112
+ clear
113
+ # merge replacement settings
114
+ merge!( other_hash )
115
+ update_self_as_cascading_composite
116
+ return self
117
+ end
118
+
119
+ ###########
120
+ # shift #
121
+ ###########
122
+
123
+ def shift
124
+ element = super
125
+ key = element[ 0 ]
126
+ @local_cascading_hash.delete( key )
127
+ update_removing_composite_elements( key )
128
+ return element
129
+ end
130
+
131
+ ###########
132
+ # clear #
133
+ ###########
134
+
135
+ alias_method :super_clear, :clear
136
+ def clear
137
+ # add all existing values to exclude array
138
+ keys.each do |this_key|
139
+ delete( this_key )
140
+ end
141
+ update_removing_composite_elements( *self.keys )
142
+ return self
143
+ end
144
+
145
+ #############
146
+ # freeze! #
147
+ #############
148
+
149
+ # freezes configuration and prevents ancestors from changing this configuration in the future
150
+ def freeze!
151
+
152
+ # move current configuration into local configuration
153
+ @local_cascading_hash.replace( self )
154
+
155
+ # unregister with parent composite so we don't get future updates from it
156
+ @super_composite_hash.unregister_sub_composite_hash( self ) if @super_composite_hash
157
+
158
+ return self
159
+
160
+ end
161
+
162
+ ###########################################################################################################
163
+ private ###############################################################################################
164
+ ###########################################################################################################
165
+
166
+ ########################################
167
+ # update_self_as_cascading_composite #
168
+ ########################################
169
+
170
+ def update_self_as_cascading_composite
171
+ # start fresh
172
+ super_clear
173
+ update_composite_self_for_parent_hash( @super_composite_hash, @local_cascading_hash )
174
+ # remove local exclude
175
+ unless @local_cascading_hash.exclude_array.empty?
176
+ @local_cascading_hash.exclude_array.each do |this_excluded_element|
177
+ super_delete( this_excluded_element )
178
+ end
179
+ end
180
+ # notify children to update their composite status
181
+ update_sub_composite_arrays
182
+ return self
183
+ end
184
+
185
+ ######################################
186
+ # update_adding_composite_elements #
187
+ ######################################
188
+
189
+ def update_adding_composite_elements( elements_to_cascade )
190
+ update_composite_self_for_parent_hash( self, elements_to_cascade )
191
+ update_sub_composite_arrays
192
+ return self
193
+ end
194
+
195
+ ###########################################
196
+ # update_composite_self_for_parent_hash #
197
+ ###########################################
198
+
199
+ def update_composite_self_for_parent_hash( parent_hash, second_hash )
200
+
201
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( @configuration_instance )
202
+ for_instance = false
203
+
204
+ if ! module_configuration_support_module and ! is_a?( Module )
205
+ module_configuration_support_module = CascadingConfiguration::Variable.module_configuration_support_module( @configuration_instance.class )
206
+ for_instance = true
207
+ end
208
+
209
+ if compositing_proc = module_configuration_support_module.get_compositing_proc( @configuration_name, for_instance )
210
+ # if we have a compositing proc defined, use its result to replace
211
+ parent_hash_copy = Hash.new
212
+ parent_hash_copy.merge!( parent_hash ) if parent_hash
213
+ second_hash_copy = Hash.new
214
+ second_hash_copy.merge!( second_hash ) if second_hash
215
+ composite_result = compositing_proc.call( parent_hash_copy, second_hash_copy )
216
+ super_replace( composite_result )
217
+ else
218
+ # otherwise we simply merge
219
+ super_merge!( parent_hash ) if parent_hash
220
+ super_merge!( second_hash ) if second_hash
221
+ end
222
+ return self
223
+ end
224
+
225
+ ########################################
226
+ # update_removing_composite_elements #
227
+ ########################################
228
+
229
+ def update_removing_composite_elements( *elements_to_exclude )
230
+ elements_to_exclude.each do |this_key|
231
+ super_delete( this_key )
232
+ end
233
+ update_sub_composite_arrays
234
+ end
235
+
236
+ ###################################
237
+ # update_sub_composite_arrays #
238
+ ###################################
239
+
240
+ def update_sub_composite_arrays
241
+ @sub_composite_hashes.each do |this_composite_hash|
242
+ this_composite_hash.instance_eval { update_self_as_cascading_composite }
243
+ end
244
+ end
245
+
246
+ end