cascading_configuration 1.0.2 → 1.0.3
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 +3 -0
- data/lib/cascading_configuration/core/instance_controller.rb +101 -28
- data/lib/cascading_configuration/core/instance_controller/extension_module.rb +62 -2
- data/lib/cascading_configuration/core/module.rb +3 -3
- data/spec/cascading_configuration/core/instance_controller/extension_module_spec.rb +27 -0
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -38,3 +38,6 @@ Added :initialize_configuration to CascadingConfiguration::Core::Module; subclas
|
|
38
38
|
Renamed project from cascading-configuration to cascading_configuration to match Rubygems guidelines for gem naming.
|
39
39
|
Ensured configurations don't re-register parents that are higher in the ancestor chain than the ones already registered.
|
40
40
|
|
41
|
+
## 7/15/2012
|
42
|
+
|
43
|
+
Added support in extension modules for aliasing methods that will exist in object extended by extension module but does not exist yet in extension module.
|
@@ -80,14 +80,12 @@ class ::CascadingConfiguration::Core::InstanceController < ::Module
|
|
80
80
|
@instance = instance.extend( self )
|
81
81
|
|
82
82
|
if @instance.is_a?( ::Module )
|
83
|
-
|
83
|
+
initialize_constant_in_instance( constant )
|
84
84
|
unless extending
|
85
85
|
initialize_inheritance( @instance )
|
86
86
|
end
|
87
87
|
else
|
88
|
-
|
89
|
-
constant = 'ID_' << hex_id_string
|
90
|
-
self.class.const_set( constant, self )
|
88
|
+
initialize_constant_in_self
|
91
89
|
end
|
92
90
|
|
93
91
|
# We manage reference to self in singleton from here to avoid duplicative efforts.
|
@@ -111,6 +109,30 @@ class ::CascadingConfiguration::Core::InstanceController < ::Module
|
|
111
109
|
@extension_modules = { }
|
112
110
|
|
113
111
|
end
|
112
|
+
|
113
|
+
#################################
|
114
|
+
# initialize_constant_in_self #
|
115
|
+
#################################
|
116
|
+
|
117
|
+
def initialize_constant_in_instance( constant )
|
118
|
+
|
119
|
+
@instance.const_set( constant, self )
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
#################################
|
124
|
+
# initialize_constant_in_self #
|
125
|
+
#################################
|
126
|
+
|
127
|
+
def initialize_constant_in_self
|
128
|
+
|
129
|
+
hex_id_string = '0x%x' % ( @instance.__id__ << 1 )
|
130
|
+
constant = 'ID_' << hex_id_string
|
131
|
+
self.class.const_set( constant, self )
|
132
|
+
|
133
|
+
return self
|
134
|
+
|
135
|
+
end
|
114
136
|
|
115
137
|
####################################
|
116
138
|
# initialize_inheriting_instance #
|
@@ -127,31 +149,82 @@ class ::CascadingConfiguration::Core::InstanceController < ::Module
|
|
127
149
|
|
128
150
|
# subclass eigenclass inheritance is automatic; re-extending will only mess it up
|
129
151
|
unless for_subclass
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
152
|
+
initialize_inheriting_instance_includes_extends( parent_instance, instance, is_extending )
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
#####################################################
|
158
|
+
# initialize_inheriting_instance_includes_extends #
|
159
|
+
#####################################################
|
160
|
+
|
161
|
+
def initialize_inheriting_instance_includes_extends( parent_instance, instance, is_extending = false )
|
162
|
+
|
163
|
+
unless is_extending or @cascade_extends.empty?
|
164
|
+
initialize_inheriting_instance_extends( parent_instance, instance )
|
165
|
+
end
|
166
|
+
|
167
|
+
unless @cascade_includes.empty?
|
168
|
+
|
169
|
+
if is_extending
|
170
|
+
initialize_inheriting_instance_includes_for_extend_crossover( parent_instance, instance )
|
171
|
+
else
|
172
|
+
initialize_inheriting_instance_includes( parent_instance, instance )
|
134
173
|
end
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
#############################################
|
180
|
+
# initialize_inheriting_instance_includes #
|
181
|
+
#############################################
|
182
|
+
|
183
|
+
def initialize_inheriting_instance_includes( parent_instance, instance )
|
184
|
+
|
185
|
+
cascade_includes = @cascade_includes
|
186
|
+
|
187
|
+
instance.module_eval do
|
188
|
+
# We collect cascade extends in accumulating order (oldest => youngest),
|
189
|
+
# which means we need to reverse prior to including/extending
|
190
|
+
# (we need youngest => oldest).
|
191
|
+
include( *cascade_includes.reverse )
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
############################################
|
197
|
+
# initialize_inheriting_instance_extends #
|
198
|
+
############################################
|
199
|
+
|
200
|
+
def initialize_inheriting_instance_extends( parent_instance, instance )
|
201
|
+
|
202
|
+
# We collect cascade extends in accumulating order (oldest => youngest),
|
203
|
+
# which means we need to reverse prior to including/extending
|
204
|
+
# (we need youngest => oldest).
|
205
|
+
instance.extend( *@cascade_extends.reverse )
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
##################################################################
|
210
|
+
# initialize_inheriting_instance_includes_for_extend_crossover #
|
211
|
+
##################################################################
|
212
|
+
|
213
|
+
###
|
214
|
+
# Normally we have module => module cascading where instance methods remain instance methods,
|
215
|
+
# and singleton methods remain singleton methods. When a module extends another, however,
|
216
|
+
# instance methods become singleton methods.
|
217
|
+
#
|
218
|
+
def initialize_inheriting_instance_includes_for_extend_crossover( parent_instance, instance )
|
219
|
+
|
220
|
+
@cascade_includes.each do |this_include|
|
221
|
+
case instance
|
222
|
+
when ::Module
|
223
|
+
unless instance.ancestors.include?( this_include )
|
224
|
+
instance.extend( this_include )
|
153
225
|
end
|
154
|
-
|
226
|
+
else
|
227
|
+
instance.extend( this_include )
|
155
228
|
end
|
156
229
|
end
|
157
230
|
|
@@ -162,7 +235,7 @@ class ::CascadingConfiguration::Core::InstanceController < ::Module
|
|
162
235
|
######################################################
|
163
236
|
|
164
237
|
def initialize_encapsulation_for_inheriting_instance( encapsulation, parent_instance, instance )
|
165
|
-
|
238
|
+
|
166
239
|
encapsulation.register_child_for_parent( instance, parent_instance )
|
167
240
|
|
168
241
|
end
|
@@ -10,13 +10,25 @@ class ::CascadingConfiguration::Core::InstanceController::ExtensionModule < ::Mo
|
|
10
10
|
@instance_controller = instance_controller
|
11
11
|
@encapsulation = encapsulation
|
12
12
|
@configuration_name = configuration_name
|
13
|
-
|
13
|
+
|
14
|
+
@pending_aliases = { }
|
15
|
+
|
14
16
|
if block_given?
|
15
17
|
module_eval( & definer_block )
|
16
18
|
end
|
17
19
|
|
18
20
|
end
|
19
21
|
|
22
|
+
##############
|
23
|
+
# extended #
|
24
|
+
##############
|
25
|
+
|
26
|
+
def extended( configuration_instance )
|
27
|
+
|
28
|
+
create_pending_aliases( configuration_instance )
|
29
|
+
|
30
|
+
end
|
31
|
+
|
20
32
|
#########################
|
21
33
|
# instance_controller #
|
22
34
|
#########################
|
@@ -34,5 +46,53 @@ class ::CascadingConfiguration::Core::InstanceController::ExtensionModule < ::Mo
|
|
34
46
|
########################
|
35
47
|
|
36
48
|
attr_reader :configuration_name
|
37
|
-
|
49
|
+
|
50
|
+
############################
|
51
|
+
# create_pending_aliases #
|
52
|
+
############################
|
53
|
+
|
54
|
+
def create_pending_aliases( configuration_instance )
|
55
|
+
|
56
|
+
created_aliases = false
|
57
|
+
|
58
|
+
unless @pending_aliases.empty?
|
59
|
+
pending_aliases = @pending_aliases
|
60
|
+
eigenclass = class << configuration_instance ; self ; end
|
61
|
+
eigenclass.instance_eval do
|
62
|
+
pending_aliases.delete_if do |this_alias_name, this_method_name|
|
63
|
+
should_delete = false
|
64
|
+
if method_defined?( this_method_name )
|
65
|
+
alias_method( this_alias_name, this_method_name )
|
66
|
+
should_delete = true
|
67
|
+
end
|
68
|
+
should_delete
|
69
|
+
end
|
70
|
+
end
|
71
|
+
created_aliases = true
|
72
|
+
end
|
73
|
+
|
74
|
+
return created_aliases
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
##################
|
79
|
+
# alias_method #
|
80
|
+
##################
|
81
|
+
|
82
|
+
def alias_method( alias_name, method_name )
|
83
|
+
|
84
|
+
aliased_method = false
|
85
|
+
|
86
|
+
# if we don't respond to method, store it away so that we can alias it at extend time
|
87
|
+
if method_defined?( method_name )
|
88
|
+
super
|
89
|
+
aliased_method = true
|
90
|
+
else
|
91
|
+
@pending_aliases[ alias_name ] = method_name
|
92
|
+
end
|
93
|
+
|
94
|
+
return aliased_method
|
95
|
+
|
96
|
+
end
|
97
|
+
|
38
98
|
end
|
@@ -5,7 +5,7 @@ class ::CascadingConfiguration::Core::Module < ::Module
|
|
5
5
|
DefaultEncapsulation = ::CascadingConfiguration::Core::Encapsulation.new( DefaultEncapsulationName )
|
6
6
|
|
7
7
|
include ::CascadingConfiguration::Core::EnableModuleSupport
|
8
|
-
|
8
|
+
|
9
9
|
################
|
10
10
|
# initialize #
|
11
11
|
################
|
@@ -22,7 +22,7 @@ class ::CascadingConfiguration::Core::Module < ::Module
|
|
22
22
|
|
23
23
|
@ccm_name = ccm_name
|
24
24
|
@ccm_aliases = ccm_aliases
|
25
|
-
|
25
|
+
|
26
26
|
define_definition_methods( @ccm_name, *@ccm_aliases )
|
27
27
|
|
28
28
|
end
|
@@ -44,7 +44,7 @@ class ::CascadingConfiguration::Core::Module < ::Module
|
|
44
44
|
#################
|
45
45
|
|
46
46
|
attr_reader :ccm_aliases
|
47
|
-
|
47
|
+
|
48
48
|
###############################
|
49
49
|
# define_definition_methods #
|
50
50
|
###############################
|
@@ -22,5 +22,32 @@ describe ::CascadingConfiguration::Core::InstanceController::ExtensionModule do
|
|
22
22
|
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
##################
|
27
|
+
# alias_method #
|
28
|
+
##################
|
29
|
+
|
30
|
+
it 'can pend method aliases' do
|
31
|
+
module ::CascadingConfiguration::Core::InstanceController::ExtensionModule::AliasMethodMock
|
32
|
+
|
33
|
+
ForInstance = ::Module.new
|
34
|
+
InstanceController = ::CascadingConfiguration::Core::InstanceController.new( ForInstance )
|
35
|
+
Encapsulation = ::CascadingConfiguration::Core::Module::DefaultEncapsulation
|
36
|
+
|
37
|
+
Module_instance = ::CascadingConfiguration::Core::InstanceController::ExtensionModule.new( InstanceController, Encapsulation, :some_configuration )
|
38
|
+
|
39
|
+
Module_instance.alias_method( :alias_name, :method_in_object_but_not_module )
|
40
|
+
|
41
|
+
instance = ::Module.new do
|
42
|
+
def self.method_in_object_but_not_module
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
instance.respond_to?( :alias_name ).should == false
|
47
|
+
instance.extend( Module_instance )
|
48
|
+
instance.respond_to?( :alias_name ).should == true
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
25
52
|
|
26
53
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cascading_configuration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: module-cluster
|