cascading-configuration-hash 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/README.rdoc ADDED
@@ -0,0 +1,138 @@
1
+ == Cascading Configuration
2
+
3
+ http://rubygems.org/gems/cascading-configuration-hash
4
+
5
+ == DESCRIPTION:
6
+
7
+ Adds methods for cascading configuration hashes. Support package for cascading-configuration.
8
+
9
+ == SUMMARY:
10
+
11
+ * :attr_configuration_hash
12
+
13
+ == INSTALL:
14
+
15
+ * sudo gem install cascading-configuration-hash
16
+
17
+ == EXAMPLE:
18
+
19
+ #############################################################################
20
+ ######################### attr_configuration_hash ###########################
21
+ #############################################################################
22
+
23
+ ##################
24
+ # first module #
25
+ ##################
26
+
27
+ module CascadingConfiguration::MockModule
28
+ attr_configuration_hash :some_hash_configuration
29
+ self.some_hash_configuration = { :some_value => :some_value }
30
+ # => some_hash_configuration.should == { :some_value => :some_value }
31
+ end
32
+
33
+ ########################
34
+ # including module 1 #
35
+ ########################
36
+
37
+ module CascadingConfiguration::MockModule2
38
+ # => some_hash_configuration.should == { :some_value => :some_value }
39
+ self.some_hash_configuration = { :module_value => :some_value }
40
+ # => some_hash_configuration.should == { :module_value => :some_value }
41
+ end
42
+
43
+ ########################
44
+ # including module 2 #
45
+ ########################
46
+
47
+ module CascadingConfiguration::MockModule3
48
+
49
+ end
50
+
51
+ ###############
52
+ # top class #
53
+ ###############
54
+
55
+ class CascadingConfiguration::MockClass
56
+ # => some_hash_configuration.should == { :module_value => :some_value }
57
+ self.some_hash_configuration = { :another_value => :some_value }
58
+ # => some_hash_configuration.should == { :another_value => :some_value }
59
+ end
60
+
61
+ ###########################
62
+ # instance of top class #
63
+ ###########################
64
+
65
+ object_instance_one = CascadingConfiguration::MockClass.new
66
+ # => object_instance_one.some_hash_configuration.should == { :another_value => :some_value }
67
+ object_instance_one.some_hash_configuration = { :yet_another_value => :some_value }
68
+ # => object_instance_one.some_hash_configuration.should == { :yet_another_value => :some_value }
69
+ # => CascadingConfiguration::MockClass.some_hash_configuration.should == { :another_value => :some_value }
70
+ # => CascadingConfiguration::MockModule.some_hash_configuration.should == { :some_value => :some_value }
71
+
72
+ ############################
73
+ # first inheriting class #
74
+ ############################
75
+
76
+ class CascadingConfiguration::MockClassSub1 < CascadingConfiguration::MockClass
77
+ # => some_hash_configuration.should == { :another_value => :some_value }
78
+ self.some_hash_configuration = { :a_value_not_yet_used => :some_value }
79
+ # => some_hash_configuration.should == { :a_value_not_yet_used => :some_value }
80
+ # => CascadingConfiguration::MockClass.some_hash_configuration.should == { :another_value => :some_value }
81
+ # => CascadingConfiguration::MockModule.some_hash_configuration.should == { :some_value => :some_value }
82
+ end
83
+
84
+ ########################################
85
+ # instance of first inheriting class #
86
+ ########################################
87
+
88
+ object_instance_two = CascadingConfiguration::MockClassSub1.new
89
+ # => object_instance_two.some_hash_configuration.should == { :a_value_not_yet_used => :some_value }
90
+ # => object_instance_one.some_hash_configuration.should == { :yet_another_value => :some_value }
91
+ # => CascadingConfiguration::MockClass.some_hash_configuration.should == { :another_value => :some_value }
92
+ # => CascadingConfiguration::MockModule.some_hash_configuration.should == { :some_value => :some_value }
93
+
94
+ #############################
95
+ # second inheriting class #
96
+ #############################
97
+
98
+ class CascadingConfiguration::MockClassSub2 < CascadingConfiguration::MockClassSub1
99
+ # => some_hash_configuration.should == { :a_value_not_yet_used => :some_value }
100
+ self.some_hash_configuration = { :another_value_not_yet_used => :some_value }
101
+ # => some_hash_configuration.should == { :another_value_not_yet_used => :some_value }
102
+ end
103
+
104
+ #########################################
105
+ # instance of second inheriting class #
106
+ #########################################
107
+
108
+ object_instance_three = CascadingConfiguration::MockClassSub2.new
109
+ # => object_instance_three.some_hash_configuration.should == { :another_value_not_yet_used => :some_value }
110
+ object_instance_three.some_hash_configuration = { :one_more_unused_value => :some_value }
111
+ # => object_instance_three.some_hash_configuration.should == { :one_more_unused_value => :some_value }
112
+
113
+ #############################################################################
114
+
115
+ == LICENSE:
116
+
117
+ (The MIT License)
118
+
119
+ Copyright (c) 2011 Asher
120
+
121
+ Permission is hereby granted, free of charge, to any person obtaining
122
+ a copy of this software and associated documentation files (the
123
+ 'Software'), to deal in the Software without restriction, including
124
+ without limitation the rights to use, copy, modify, merge, publish,
125
+ distribute, sublicense, and/or sell copies of the Software, and to
126
+ permit persons to whom the Software is furnished to do so, subject to
127
+ the following conditions:
128
+
129
+ The above copyright notice and this permission notice shall be
130
+ included in all copies or substantial portions of the Software.
131
+
132
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
133
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
134
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
135
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
136
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
137
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
138
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+
2
+ module CascadingConfiguration::CascadingCompositeHash::Instance
3
+
4
+ ###################
5
+ # self.included #
6
+ ###################
7
+
8
+ def self.included( class_or_module )
9
+ module_self = self
10
+ class_or_module.instance_eval do
11
+ extend module_self
12
+ end
13
+ end
14
+
15
+ ################################################
16
+ # composite_hash_for_cascading_configuration #
17
+ ################################################
18
+
19
+ def composite_hash_for_cascading_configuration( configuration_name )
20
+
21
+ # initialize composite hash if necessary or acquire it from object
22
+ composite_hash_variable = composite_hash_variable_name( configuration_name )
23
+ composite_hash = nil
24
+ if instance_variable_defined?( composite_hash_variable )
25
+ composite_hash = instance_variable_get( composite_hash_variable )
26
+ else
27
+ composite_hash = ::CascadingConfiguration::CascadingCompositeHash.new( configuration_name, self )
28
+ instance_variable_set( composite_hash_variable, composite_hash )
29
+ end
30
+
31
+ return composite_hash
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,16 @@
1
+
2
+ module CascadingConfiguration::CascadingCompositeHash::Instance
3
+
4
+ ###########################################################################################################
5
+ private ###############################################################################################
6
+ ###########################################################################################################
7
+
8
+ ##################################
9
+ # composite_hash_variable_name #
10
+ ##################################
11
+
12
+ def composite_hash_variable_name( configuration_name )
13
+ return ( cascading_variable_name( configuration_name ).to_s + '__' + 'composite_hash' ).to_sym
14
+ end
15
+
16
+ end
@@ -0,0 +1,133 @@
1
+
2
+ class CascadingConfiguration::CascadingCompositeHash < Hash
3
+
4
+ attr_accessor :working_instance, :local_cascading_hash
5
+
6
+ ################
7
+ # initialize #
8
+ ################
9
+
10
+ def initialize( cascading_name, working_instance )
11
+ @cascading_name = cascading_name
12
+ @cascading_variable = working_instance.cascading_variable_name( @cascading_name )
13
+ @working_instance = working_instance
14
+ # if first ancestor can have a composite array, register self with it in case it gets updated in the future
15
+ if ( first_ancestor = @working_instance.first_ancestor ).respond_to?( :composite_hash_for_cascading_configuration )
16
+ @parent_composite_hash = first_ancestor.composite_hash_for_cascading_configuration( @cascading_name )
17
+ @parent_composite_hash.register_child_composite_hash( self )
18
+ end
19
+ # get local cascading array (not included in parent composite)
20
+ @local_cascading_hash = ::CascadingConfiguration::ConfigurationHash.new
21
+ # we may later have our own child composites
22
+ @child_composite_hashes = Array.new
23
+ # initialize self status for parent and local
24
+ update_self_as_cascading_composite
25
+ end
26
+
27
+ ###################################
28
+ # register_child_composite_hash #
29
+ ###################################
30
+
31
+ def register_child_composite_hash( child_composite_hash )
32
+ @child_composite_hashes.push( child_composite_hash )
33
+ return self
34
+ end
35
+
36
+ #####################################
37
+ # unregister_child_composite_hash #
38
+ #####################################
39
+
40
+ def unregister_child_composite_hash( child_composite_hash )
41
+ @child_composite_hashes.delete( child_composite_hash )
42
+ return self
43
+ end
44
+
45
+ #########
46
+ # []= #
47
+ #########
48
+
49
+ def []=( key, value )
50
+ @local_cascading_hash[ key ] = value
51
+ update_adding_composite_elements( key => value )
52
+ end
53
+ alias_method :store, :[]=
54
+
55
+ ############
56
+ # delete #
57
+ ############
58
+
59
+ alias_method :super_delete, :delete
60
+ def delete( key )
61
+ value = self[ key ]
62
+ @local_cascading_hash.delete( key )
63
+ update_removing_composite_elements( key )
64
+ return value
65
+ end
66
+
67
+ ############
68
+ # merge! #
69
+ ############
70
+
71
+ alias_method :super_merge!, :merge!
72
+ def merge!( other_hash )
73
+ @local_cascading_hash.merge!( other_hash )
74
+ update_adding_composite_elements( other_hash )
75
+ return self
76
+ end
77
+
78
+ #############
79
+ # replace #
80
+ #############
81
+
82
+ def replace( other_hash )
83
+ # clear current values
84
+ clear
85
+ # merge replacement settings
86
+ merge!( other_hash )
87
+ return self
88
+ end
89
+
90
+ ###########
91
+ # shift #
92
+ ###########
93
+
94
+ def shift
95
+ element = super
96
+ key = element[ 0 ]
97
+ @local_cascading_hash.delete( key )
98
+ update_removing_composite_elements( key )
99
+ return element
100
+ end
101
+
102
+ ###########
103
+ # clear #
104
+ ###########
105
+
106
+ alias_method :super_clear, :clear
107
+ def clear
108
+ # add all existing values to exclude array
109
+ self.keys.each do |this_key|
110
+ delete( this_key )
111
+ end
112
+ update_removing_composite_elements( *self.keys )
113
+ return self
114
+ end
115
+
116
+ #############
117
+ # freeze! #
118
+ #############
119
+
120
+ # freezes configuration and prevents ancestors from changing this configuration in the future
121
+ def freeze!
122
+
123
+ # move current configuration into local configuration
124
+ @local_cascading_hash.replace( self )
125
+
126
+ # unregister with parent composite so we don't get future updates from it
127
+ @parent_composite_hash.unregister_child_composite_hash( self ) if @parent_composite_hash
128
+
129
+ return self
130
+
131
+ end
132
+
133
+ end
@@ -0,0 +1,83 @@
1
+
2
+ class CascadingConfiguration::ConfigurationHash < Hash
3
+
4
+ attr_accessor :exclude_array
5
+
6
+ ################
7
+ # initialize #
8
+ ################
9
+
10
+ def initialize()
11
+ @exclude_array = Array.new
12
+ end
13
+
14
+ #########
15
+ # []= #
16
+ #########
17
+
18
+ def []=( key, value )
19
+ super
20
+ remove_from_exclude_array( key )
21
+ end
22
+
23
+ ###########
24
+ # store #
25
+ ###########
26
+
27
+ def store( key, value )
28
+ self[ key ] = value
29
+ end
30
+
31
+ ############
32
+ # delete #
33
+ ############
34
+
35
+ def delete( key )
36
+ value = super
37
+ add_to_exclude_array( key )
38
+ return value
39
+ end
40
+
41
+ ############
42
+ # merge! #
43
+ ############
44
+
45
+ def merge!( other_hash )
46
+ super
47
+ remove_from_exclude_array( *other_hash.keys )
48
+ return self
49
+ end
50
+
51
+ #############
52
+ # replace #
53
+ #############
54
+
55
+ def replace( other_hash )
56
+ add_to_exclude_array( *self.keys )
57
+ super
58
+ end
59
+
60
+ ###########
61
+ # shift #
62
+ ###########
63
+
64
+ def shift
65
+ element = super
66
+ add_to_exclude_array( element )
67
+ return element
68
+ end
69
+
70
+ ###########
71
+ # clear #
72
+ ###########
73
+
74
+ def clear
75
+ # add all existing values to exclude array
76
+ self.each do |this_key, this_value|
77
+ delete( this_key )
78
+ end
79
+ # clear existing values
80
+ super
81
+ end
82
+
83
+ end
@@ -0,0 +1,35 @@
1
+
2
+ module CascadingConfiguration::ConfigurationSettingsHash::Accessors
3
+
4
+ ######################################
5
+ # define_configuration_hash_setter #
6
+ ######################################
7
+
8
+ def define_configuration_hash_setter( configuration_name )
9
+ [ self, eigenclass ].each do |klass_or_eigenclass|
10
+ klass_or_eigenclass.class_eval do
11
+ configuration_setter_name = ( configuration_name.to_s + '=' ).to_sym
12
+ define_method( configuration_setter_name ) do |hash|
13
+ # we want the hash to supplant existing config
14
+ return composite_hash_for_cascading_configuration( configuration_name ).replace( hash )
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ ######################################
21
+ # define_configuration_hash_getter #
22
+ ######################################
23
+
24
+ def define_configuration_hash_getter( configuration_name )
25
+ configuration_getter_name = configuration_name
26
+ [ self, eigenclass ].each do |klass_or_eigenclass|
27
+ klass_or_eigenclass.class_eval do
28
+ define_method( configuration_getter_name ) do
29
+ return composite_hash_for_cascading_configuration( configuration_name )
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,21 @@
1
+
2
+ module CascadingConfiguration::ConfigurationSettingsHash::ClassInstance
3
+
4
+ #############################
5
+ # attr_configuration_hash #
6
+ #############################
7
+
8
+ def attr_configuration_hash( *property_names )
9
+
10
+ property_names.each do |this_property_name|
11
+ # define configuration setter
12
+ define_configuration_hash_setter( this_property_name )
13
+ # define configuration getter
14
+ define_configuration_hash_getter( this_property_name )
15
+ end
16
+
17
+ return self
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,20 @@
1
+
2
+ module CascadingConfiguration::ConfigurationSettingsHash::ModuleInstance
3
+
4
+ ##############
5
+ # included #
6
+ ##############
7
+
8
+ def included( class_or_module )
9
+ self_module = self
10
+ class_or_module.instance_eval do
11
+ include CascadingConfiguration::ConfigurationSettingsHash
12
+ # when we extend a module (which has happened if we got here)
13
+ # then we need to make sure when the module we are extending is included
14
+ # * CascadingConfiguration is included
15
+ # * the module we extended is used to extend the class/module that included
16
+ extend self_module
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,21 @@
1
+
2
+ module CascadingConfiguration::ConfigurationSettingsHash
3
+
4
+ ###################
5
+ # self.included #
6
+ ###################
7
+
8
+ def self.included( class_or_module )
9
+ class_or_module.instance_eval do
10
+ include CascadingConfiguration::ConfigurationVariable
11
+ extend CascadingConfiguration::ConfigurationSettingsHash
12
+ extend CascadingConfiguration::ConfigurationSettingsHash::Accessors
13
+ extend CascadingConfiguration::ConfigurationSettingsHash::ClassInstance
14
+ include CascadingConfiguration::CascadingCompositeHash::Instance
15
+ unless class_or_module.is_a?( Class )
16
+ extend CascadingConfiguration::ConfigurationSettingsHash::ModuleInstance
17
+ end
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,60 @@
1
+
2
+ class CascadingConfiguration::CascadingCompositeHash < Hash
3
+
4
+ ###########################################################################################################
5
+ private ###############################################################################################
6
+ ###########################################################################################################
7
+
8
+ ########################################
9
+ # update_self_as_cascading_composite #
10
+ ########################################
11
+
12
+ def update_self_as_cascading_composite
13
+ # start fresh
14
+ super_clear
15
+ # add parent config
16
+ super_merge!( @parent_composite_hash ) if @parent_composite_hash
17
+ # add additional local config
18
+ super_merge!( @local_cascading_hash )
19
+ # remove local exclude
20
+ unless @local_cascading_hash.exclude_array.empty?
21
+ @local_cascading_hash.exclude_array.each do |this_excluded_element|
22
+ super_delete( this_excluded_element )
23
+ end
24
+ end
25
+ # notify children to update their composite status
26
+ update_child_composite_arrays
27
+ return self
28
+ end
29
+
30
+ ######################################
31
+ # update_adding_composite_elements #
32
+ ######################################
33
+
34
+ def update_adding_composite_elements( elements_to_cascade )
35
+ super_merge!( elements_to_cascade )
36
+ update_child_composite_arrays
37
+ end
38
+
39
+ ########################################
40
+ # update_removing_composite_elements #
41
+ ########################################
42
+
43
+ def update_removing_composite_elements( *elements_to_exclude )
44
+ elements_to_exclude.each do |this_key|
45
+ super_delete( this_key )
46
+ end
47
+ update_child_composite_arrays
48
+ end
49
+
50
+ ###################################
51
+ # update_child_composite_arrays #
52
+ ###################################
53
+
54
+ def update_child_composite_arrays
55
+ @child_composite_hashes.each do |this_composite_hash|
56
+ this_composite_hash.instance_eval { update_self_as_cascading_composite }
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,31 @@
1
+
2
+ class CascadingConfiguration::ConfigurationHash < Hash
3
+
4
+ ###########################################################################################################
5
+ private ###############################################################################################
6
+ ###########################################################################################################
7
+
8
+ ##########################
9
+ # add_to_exclude_array #
10
+ ##########################
11
+
12
+ def add_to_exclude_array( *elements )
13
+ @exclude_array ||= Array.new
14
+ @exclude_array += elements
15
+ @exclude_array.sort!.uniq!
16
+ end
17
+
18
+ ###############################
19
+ # remove_from_exclude_array #
20
+ ###############################
21
+
22
+ def remove_from_exclude_array( *elements )
23
+ if @exclude_array
24
+ @exclude_array -= elements
25
+ @exclude_array.sort!.uniq!
26
+ else
27
+ @exclude_array ||= Array.new
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,33 @@
1
+
2
+ require 'cascading-configuration-variable'
3
+ #require_relative '../../variable/lib/cascading-configuration-variable.rb'
4
+
5
+ module CascadingConfiguration
6
+ class CascadingCompositeHash < Hash
7
+ module Instance
8
+ end
9
+ end
10
+ class ConfigurationHash < Hash
11
+ end
12
+ module ConfigurationSettingsHash
13
+ module Accessors
14
+ end
15
+ module ClassInstance
16
+ end
17
+ module ObjectInstance
18
+ end
19
+ module ModuleInstance
20
+ end
21
+ end
22
+ end
23
+
24
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/CascadingCompositeHash.rb'
25
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/_private_/CascadingCompositeHash.rb'
26
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/CascadingCompositeHash/Instance.rb'
27
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/CascadingCompositeHash/_private_/Instance.rb'
28
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/ConfigurationHash.rb'
29
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/_private_/ConfigurationHash.rb'
30
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/ConfigurationSettingsHash.rb'
31
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/ConfigurationSettingsHash/Accessors.rb'
32
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/ConfigurationSettingsHash/ClassInstance.rb'
33
+ require_relative 'cascading-configuration-hash/CascadingConfiguration/ConfigurationSettingsHash/ModuleInstance.rb'