module-cluster 1.4.8 → 2.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 (108) hide show
  1. data/README.md +127 -337
  2. data/lib/module-cluster.rb +1 -153
  3. data/lib/module/cluster.rb +341 -0
  4. data/lib/module/cluster/class_support.rb +22 -0
  5. data/lib/module/cluster/cluster.rb +10 -0
  6. data/lib/module/cluster/cluster/cluster_interface.rb +550 -0
  7. data/lib/module/cluster/exception/module_not_in_stack.rb +26 -0
  8. data/lib/module/cluster/instance_controller.rb +14 -0
  9. data/lib/module/cluster/instance_controller/hook_controller.rb +33 -0
  10. data/lib/module/cluster/instance_controller/hook_controller/chain_proxy.rb +511 -0
  11. data/lib/module/cluster/instance_controller/hook_controller/hook_controller_interface.rb +830 -0
  12. data/lib/module/cluster/instance_controller/instance_controller_interface.rb +269 -0
  13. data/lib/module/cluster/instance_controller/multiple_hook_controller_proxy.rb +359 -0
  14. data/lib/module/cluster/instance_controller/multiple_hook_controller_proxy/chain_proxy.rb +442 -0
  15. data/lib/module/cluster/module_support.rb +67 -0
  16. data/lib/module/namespaces.rb +13 -0
  17. data/lib/module/requires.rb +32 -0
  18. data/spec/module/cluster/cluster_spec.rb +473 -0
  19. data/spec/module/cluster/instance_controller/hook_controller_spec.rb +922 -0
  20. data/spec/module/cluster/instance_controller/multiple_hook_controller_proxy_spec.rb +1240 -0
  21. data/spec/module/cluster_spec.rb +1794 -0
  22. metadata +27 -98
  23. data/README.rdoc +0 -395
  24. data/lib/module-cluster/ModuleCluster.rb +0 -9
  25. data/lib/module-cluster/ModuleCluster/Define.rb +0 -12
  26. data/lib/module-cluster/ModuleCluster/Define/Block.rb +0 -9
  27. data/lib/module-cluster/ModuleCluster/Define/Block/CascadingClass.rb +0 -83
  28. data/lib/module-cluster/ModuleCluster/Define/Block/CascadingClassOrModule.rb +0 -70
  29. data/lib/module-cluster/ModuleCluster/Define/Block/CascadingModule.rb +0 -79
  30. data/lib/module-cluster/ModuleCluster/Define/Block/CascadingModuleOrSubclass.rb +0 -21
  31. data/lib/module-cluster/ModuleCluster/Define/Block/Class.rb +0 -77
  32. data/lib/module-cluster/ModuleCluster/Define/Block/ClassOrInstance.rb +0 -78
  33. data/lib/module-cluster/ModuleCluster/Define/Block/ClassOrModule.rb +0 -78
  34. data/lib/module-cluster/ModuleCluster/Define/Block/ClassOrModuleOrInstance.rb +0 -78
  35. data/lib/module-cluster/ModuleCluster/Define/Block/ClassOrModuleOrSubclass.rb +0 -36
  36. data/lib/module-cluster/ModuleCluster/Define/Block/ClassOrSubclass.rb +0 -29
  37. data/lib/module-cluster/ModuleCluster/Define/Block/Instance.rb +0 -45
  38. data/lib/module-cluster/ModuleCluster/Define/Block/Module.rb +0 -77
  39. data/lib/module-cluster/ModuleCluster/Define/Block/ModuleOrInstance.rb +0 -78
  40. data/lib/module-cluster/ModuleCluster/Define/Block/ModuleOrSubclass.rb +0 -29
  41. data/lib/module-cluster/ModuleCluster/Define/Block/Subclass.rb +0 -56
  42. data/lib/module-cluster/ModuleCluster/Define/ClassCluster.rb +0 -193
  43. data/lib/module-cluster/ModuleCluster/Define/ClassOrInstanceCluster.rb +0 -128
  44. data/lib/module-cluster/ModuleCluster/Define/Cluster.rb +0 -181
  45. data/lib/module-cluster/ModuleCluster/Define/ClusterCascades.rb +0 -185
  46. data/lib/module-cluster/ModuleCluster/Define/ClusterCascadesToClass.rb +0 -181
  47. data/lib/module-cluster/ModuleCluster/Define/ClusterCascadesToModule.rb +0 -181
  48. data/lib/module-cluster/ModuleCluster/Define/Deprecated.rb +0 -40
  49. data/lib/module-cluster/ModuleCluster/Define/InstanceCluster.rb +0 -45
  50. data/lib/module-cluster/ModuleCluster/Define/ModuleCluster.rb +0 -193
  51. data/lib/module-cluster/ModuleCluster/Define/ModuleOrClassCluster.rb +0 -209
  52. data/lib/module-cluster/ModuleCluster/Define/ModuleOrInstanceCluster.rb +0 -128
  53. data/lib/module-cluster/ModuleCluster/Define/Status.rb +0 -106
  54. data/lib/module-cluster/ModuleCluster/Suspend.rb +0 -7
  55. data/lib/module-cluster/ModuleCluster/Suspend/Hooks.rb +0 -315
  56. data/lib/module-cluster/ModuleCluster/Suspend/WithoutHooks.rb +0 -153
  57. data/lib/module-cluster/_private_/ModuleCluster/CascadeFeatures.rb +0 -77
  58. data/lib/module-cluster/_private_/ModuleCluster/CascadeFeatures/ClusterStack.rb +0 -44
  59. data/lib/module-cluster/_private_/ModuleCluster/CascadeFeatures/PerformCascades.rb +0 -292
  60. data/lib/module-cluster/_private_/ModuleCluster/CascadeFeatures/Subclass.rb +0 -24
  61. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack.rb +0 -12
  62. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Block.rb +0 -9
  63. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Block/Class.rb +0 -36
  64. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Block/Inherited.rb +0 -20
  65. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Block/Instance.rb +0 -20
  66. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Block/Module.rb +0 -36
  67. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Block/Set.rb +0 -6
  68. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Extends.rb +0 -140
  69. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Includes.rb +0 -110
  70. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/PrependsExtends.rb +0 -140
  71. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/PrependsIncludes.rb +0 -110
  72. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Set.rb +0 -35
  73. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Set/MultiSetProxy.rb +0 -359
  74. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Status.rb +0 -55
  75. data/lib/module-cluster/_private_/ModuleCluster/ClusterStack/Suspend.rb +0 -199
  76. data/lib/module-cluster/_private_/ModuleCluster/ExtendForCascade.rb +0 -34
  77. data/spec/ModuleCluster/Define/Block/CascadingClassOrModule_spec.rb +0 -285
  78. data/spec/ModuleCluster/Define/Block/CascadingClass_spec.rb +0 -254
  79. data/spec/ModuleCluster/Define/Block/CascadingModuleOrSubclass_spec.rb +0 -56
  80. data/spec/ModuleCluster/Define/Block/CascadingModule_spec.rb +0 -278
  81. data/spec/ModuleCluster/Define/Block/ClassOrInstance_spec.rb +0 -230
  82. data/spec/ModuleCluster/Define/Block/ClassOrModuleOrInstance_spec.rb +0 -238
  83. data/spec/ModuleCluster/Define/Block/ClassOrModuleOrSubclass_spec.rb +0 -54
  84. data/spec/ModuleCluster/Define/Block/ClassOrModule_spec.rb +0 -231
  85. data/spec/ModuleCluster/Define/Block/ClassOrSubclass_spec.rb +0 -54
  86. data/spec/ModuleCluster/Define/Block/Class_spec.rb +0 -224
  87. data/spec/ModuleCluster/Define/Block/Instance_spec.rb +0 -78
  88. data/spec/ModuleCluster/Define/Block/ModuleOrInstance_spec.rb +0 -54
  89. data/spec/ModuleCluster/Define/Block/ModuleOrSubclass_spec.rb +0 -51
  90. data/spec/ModuleCluster/Define/Block/Module_spec.rb +0 -230
  91. data/spec/ModuleCluster/Define/Block/Subclass_spec.rb +0 -73
  92. data/spec/ModuleCluster/Define/Block_spec.rb +0 -18
  93. data/spec/ModuleCluster/Define/ClassCluster_spec.rb +0 -728
  94. data/spec/ModuleCluster/Define/ClassOrInstanceCluster_spec.rb +0 -576
  95. data/spec/ModuleCluster/Define/ClusterCascadesToClass_spec.rb +0 -659
  96. data/spec/ModuleCluster/Define/ClusterCascadesToModule_spec.rb +0 -678
  97. data/spec/ModuleCluster/Define/ClusterCascades_spec.rb +0 -644
  98. data/spec/ModuleCluster/Define/Cluster_spec.rb +0 -708
  99. data/spec/ModuleCluster/Define/InstanceCluster_spec.rb +0 -102
  100. data/spec/ModuleCluster/Define/ModuleCluster_spec.rb +0 -728
  101. data/spec/ModuleCluster/Define/ModuleOrClassCluster_spec.rb +0 -728
  102. data/spec/ModuleCluster/Define/ModuleOrInstanceCluster_spec.rb +0 -576
  103. data/spec/ModuleCluster/Suspend/Hooks_spec.rb +0 -573
  104. data/spec/ModuleCluster/Suspend/WithoutHooks_spec.rb +0 -559
  105. data/spec/ModuleCluster_spec.rb +0 -15
  106. data/spec/_private_/ModuleCluster/CascadeFeatures/PerformCascades_spec.rb +0 -386
  107. data/spec/_private_/ModuleCluster/ClusterStack/Set/MultiSetProxy_spec.rb +0 -419
  108. data/spec/_private_/ModuleCluster/ClusterStack/Suspend_spec.rb +0 -242
@@ -0,0 +1,830 @@
1
+
2
+ ###
3
+ # Interface implementation for
4
+ # {::Module::Cluster::InstanceController::HookController Module::Cluster::InstanceController::HookController}.
5
+ # Implementation provided separately for ease of overloading.
6
+ #
7
+ module ::Module::Cluster::InstanceController::HookController::HookControllerInterface
8
+
9
+ ###
10
+ # Struct used to store event frames for processing at time of event (include/extend/subclass).
11
+ #
12
+ FrameStruct = ::Struct.new( :owner, :cluster, :context, :cascades, :block, :module, :action )
13
+
14
+ ################
15
+ # initialize #
16
+ ################
17
+
18
+ ###
19
+ # @private
20
+ #
21
+ # @param name Name of this Hook Controller.
22
+ #
23
+ # @param parent_instance_controller Instance controller for which this Hook Controller is operative.
24
+ #
25
+ def initialize( name, parent_instance_controller )
26
+
27
+ @name = name
28
+
29
+ @parent_instance_controller = parent_instance_controller
30
+
31
+ @instance = @parent_instance_controller.instance
32
+
33
+ @stack = [ ]
34
+
35
+ @extend_modules = { }
36
+ @include_modules = { }
37
+
38
+ end
39
+
40
+ #############
41
+ # include #
42
+ #############
43
+
44
+ ###
45
+ # Declare that modules should be included at event hook.
46
+ #
47
+ # @overload include( module, ..., & block )
48
+ #
49
+ # @param module Module to include at event hook.
50
+ #
51
+ # @yield [hooked_instance] Block for event hook action.
52
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
53
+ # Equivalent to parameter for #included and #extended.
54
+ #
55
+ # @return [Module::Cluster::InstanceController::HookController] self
56
+ #
57
+ def include( *modules, & block )
58
+
59
+ include_at_index( -1, nil, nil, nil, false, *modules, & block )
60
+
61
+ return self
62
+
63
+ end
64
+
65
+ ############
66
+ # extend #
67
+ ############
68
+
69
+ ###
70
+ # Declare that modules should be extended at event hook.
71
+ #
72
+ # @overload extend( module, ..., & block )
73
+ #
74
+ # @param module Module to extend at event hook.
75
+ #
76
+ # @yield [hooked_instance] Block for event hook action.
77
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
78
+ # Equivalent to parameter for #included and #extended.
79
+ #
80
+ # @return [Module::Cluster::InstanceController::HookController] self
81
+ #
82
+ def extend( *modules, & block )
83
+
84
+ extend_at_index( -1, nil, nil, nil, false, *modules, & block )
85
+
86
+ return self
87
+
88
+ end
89
+
90
+ ########################
91
+ # include_and_extend #
92
+ ########################
93
+
94
+ ###
95
+ # Declare that modules should be included and extended at event hook. See also #extend_and_include.
96
+ #
97
+ # @overload include_and_extend( module, ..., & block )
98
+ #
99
+ # @param module Module to include and extend at event hook.
100
+ #
101
+ # @yield [hooked_instance] Block for event hook action.
102
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
103
+ # Equivalent to parameter for #included and #extended.
104
+ #
105
+ # @return [Module::Cluster::InstanceController::HookController] self
106
+ #
107
+ def include_and_extend( *modules, & block )
108
+
109
+ modules.each do |this_module|
110
+ include( this_module, & block )
111
+ extend( this_module, & block )
112
+ end
113
+
114
+ return self
115
+
116
+ end
117
+
118
+ ########################
119
+ # extend_and_include #
120
+ ########################
121
+
122
+ ###
123
+ # Declare that modules should be extended and included at event hook. Order is reversed from #include_and_extend.
124
+ #
125
+ # @overload extend_and_include( module, ..., & block )
126
+ #
127
+ # @param module Module to extend and include at event hook.
128
+ #
129
+ # @yield [hooked_instance] Block for event hook action.
130
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
131
+ # Equivalent to parameter for #included and #extended.
132
+ #
133
+ # @return [Module::Cluster::InstanceController::HookController] self
134
+ #
135
+ def extend_and_include( *modules, & block )
136
+
137
+ modules.each do |this_module|
138
+ extend( this_module, & block )
139
+ include( this_module, & block )
140
+ end
141
+
142
+ return self
143
+
144
+ end
145
+
146
+ ############
147
+ # action #
148
+ ############
149
+
150
+ ###
151
+ # Declare that action should be performed at event hook.
152
+ #
153
+ # @yield [hooked_instance] Block for event hook action.
154
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
155
+ # Equivalent to parameter for #included and #extended.
156
+ #
157
+ # @return [Module::Cluster::InstanceController::HookController] self
158
+ #
159
+ def action( & block )
160
+
161
+ action_at_index( -1, nil, nil, nil, false, & block )
162
+
163
+ return self
164
+
165
+ end
166
+
167
+ ###################
168
+ # before_extend #
169
+ ###################
170
+
171
+ ###
172
+ # Declare that chained actions should be inserted into the event stack prior to the location
173
+ # in the same event stack where provided module(s) are specified to be extended.
174
+ #
175
+ # @overload before_extend( module, ..., & block )
176
+ #
177
+ # @param module Module that insert should be prior to.
178
+ #
179
+ # @yield [hooked_instance] Block for event hook action.
180
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
181
+ # Equivalent to parameter for #included and #extended.
182
+ #
183
+ # @return [Module::Cluster::InstanceController::HookController::ChainProxy] Chain Proxy for chained declarations.
184
+ #
185
+ def before_extend( *modules, & block )
186
+
187
+ before_module_index = lowest_index( :extend, *modules )
188
+
189
+ proxy = chain_proxy
190
+
191
+ proxy.index( before_module_index )
192
+
193
+ if block_given?
194
+ proxy.action( & block )
195
+ end
196
+
197
+ return proxy
198
+
199
+ end
200
+
201
+ ####################
202
+ # before_include #
203
+ ####################
204
+
205
+ ###
206
+ # Declare that chained actions should be inserted into the event stack prior to the location
207
+ # in the same event stack where provided module(s) are specified to be included.
208
+ #
209
+ # @overload before_include( module, ..., & block )
210
+ #
211
+ # @param module Module that insert should be prior to.
212
+ #
213
+ # @yield [hooked_instance] Block for event hook action.
214
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
215
+ # Equivalent to parameter for #included and #extended.
216
+ #
217
+ # @return [Module::Cluster::InstanceController::HookController::ChainProxy] Chain Proxy for chained declarations.
218
+ #
219
+ def before_include( *modules, & block )
220
+
221
+ before_module_index = lowest_index( :include, *modules )
222
+
223
+ proxy = chain_proxy
224
+
225
+ proxy.index( before_module_index )
226
+
227
+ if block_given?
228
+ proxy.action( & block )
229
+ end
230
+
231
+ return proxy
232
+
233
+ end
234
+
235
+ ##############################
236
+ # before_include_or_extend #
237
+ # before_extend_or_include #
238
+ ##############################
239
+
240
+ ###
241
+ # Declare that chained actions should be inserted into the event stack prior to the location
242
+ # in the same event stack where provided module(s) are specified to be included or extended.
243
+ #
244
+ # @overload before_include_or_extend( module, ..., & block )
245
+ #
246
+ # @param module Module that insert should be prior to.
247
+ #
248
+ # @yield [hooked_instance] Block for event hook action.
249
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
250
+ # Equivalent to parameter for #included and #extended.
251
+ #
252
+ # @return [Module::Cluster::InstanceController::HookController::ChainProxy] Chain Proxy for chained declarations.
253
+ #
254
+ def before_include_or_extend( *modules, & block )
255
+
256
+ before_module_index = lowest_index( :include_or_extend, *modules )
257
+
258
+ proxy = chain_proxy
259
+
260
+ proxy.index( before_module_index )
261
+
262
+ if block_given?
263
+ proxy.action( & block )
264
+ end
265
+
266
+ return proxy
267
+
268
+ end
269
+
270
+ alias_method :before_extend_or_include, :before_include_or_extend
271
+
272
+ ###################
273
+ # after_include #
274
+ ###################
275
+
276
+ ###
277
+ # Declare that chained actions should be inserted into the event stack after the location
278
+ # in the same event stack where provided module(s) are specified to be included.
279
+ #
280
+ # @overload before_include( module, ..., & block )
281
+ #
282
+ # @param module Module that insert should be after.
283
+ #
284
+ # @yield [hooked_instance] Block for event hook action.
285
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
286
+ # Equivalent to parameter for #included and #extended.
287
+ #
288
+ # @return [Module::Cluster::InstanceController::HookController::ChainProxy] Chain Proxy for chained declarations.
289
+ #
290
+ def after_include( *modules, & block )
291
+
292
+ after_module_index = highest_index( :include, *modules ) + 1
293
+
294
+ proxy = chain_proxy
295
+
296
+ proxy.index( after_module_index )
297
+
298
+ if block_given?
299
+ proxy.action( & block )
300
+ end
301
+
302
+ return proxy
303
+
304
+ end
305
+
306
+ ##################
307
+ # after_extend #
308
+ ##################
309
+
310
+ ###
311
+ # Declare that chained actions should be inserted into the event stack after the location
312
+ # in the same event stack where provided module(s) are specified to be extended.
313
+ #
314
+ # @overload before_extend( module, ..., & block )
315
+ #
316
+ # @param module Module that insert should be after.
317
+ #
318
+ # @yield [hooked_instance] Block for event hook action.
319
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
320
+ # Equivalent to parameter for #included and #extended.
321
+ #
322
+ # @return [Module::Cluster::InstanceController::HookController::ChainProxy] Chain Proxy for chained declarations.
323
+ #
324
+ def after_extend( *modules, & block )
325
+
326
+ after_module_index = highest_index( :extend, *modules ) + 1
327
+
328
+ proxy = chain_proxy
329
+
330
+ proxy.index( after_module_index )
331
+
332
+ if block_given?
333
+ proxy.action( & block )
334
+ end
335
+
336
+ return proxy
337
+
338
+ end
339
+
340
+ #############################
341
+ # after_include_or_extend #
342
+ # after_extend_or_include #
343
+ #############################
344
+
345
+ ###
346
+ # Declare that chained actions should be inserted into the event stack after the location
347
+ # in the same event stack where provided module(s) are specified to be included or extended.
348
+ #
349
+ # @overload before_include_or_extend( module, ..., & block )
350
+ #
351
+ # @param module Module that insert should be after.
352
+ #
353
+ # @yield [hooked_instance] Block for event hook action.
354
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
355
+ # Equivalent to parameter for #included and #extended.
356
+ #
357
+ # @return [Module::Cluster::InstanceController::HookController::ChainProxy] Chain Proxy for chained declarations.
358
+ #
359
+ def after_include_or_extend( *modules, & block )
360
+
361
+ after_module_index = highest_index( :include_or_extend, *modules ) + 1
362
+
363
+ proxy = chain_proxy
364
+
365
+ proxy.index( after_module_index )
366
+
367
+ if block_given?
368
+ proxy.action( & block )
369
+ end
370
+
371
+ return proxy
372
+
373
+ end
374
+
375
+ alias_method :after_extend_or_include, :after_include_or_extend
376
+
377
+ ######################################################################################################################
378
+ # private ##########################################################################################################
379
+ ######################################################################################################################
380
+
381
+ ###
382
+ # These methods are not actually in private space but are internal methods for inter-object
383
+ # communications. They aren't intended for public interfacing.
384
+ #
385
+
386
+ ###########
387
+ # stack #
388
+ ###########
389
+
390
+ ###
391
+ # @private
392
+ #
393
+ # Each hook controller maintains a stack of event hooks to iterate at each include/extend/subclass event.
394
+ #
395
+ # @!attribute [reader] Stack of event hooks.
396
+ #
397
+ # @return [Array] Stack of event hooks.
398
+ #
399
+ attr_reader :stack
400
+
401
+ ##########
402
+ # name #
403
+ ##########
404
+
405
+ ###
406
+ # @private
407
+ #
408
+ # Name of hook controller.
409
+ #
410
+ # @return [Symbol,String] Name.
411
+ #
412
+ attr_reader :name
413
+
414
+ ################################
415
+ # parent_instance_controller #
416
+ ################################
417
+
418
+ ###
419
+ # @private
420
+ #
421
+ # @!attribute [reader] Reference to instance controller for which this hook controller operates.
422
+ #
423
+ # @return [Module::Cluster::InstanceController]
424
+ #
425
+ attr_reader :parent_instance_controller
426
+
427
+ ######################
428
+ # include_at_index #
429
+ ######################
430
+
431
+ ###
432
+ # @private
433
+ #
434
+ # Used by ChainProxy to insert modules before/after other modules.
435
+ #
436
+ # @param index Index where include should occur.
437
+ #
438
+ # @param cluster_name Name of cluster for which include event is to occur.
439
+ #
440
+ # @param contexts Contexts for which event hooks should occur.
441
+ #
442
+ # @param cascade_to Contexts for which event hooks should cascade.
443
+ #
444
+ # @param explicit_set Whether insert is an implicit position or an explicitly requested position.
445
+ #
446
+ # @param modules Modules to include.
447
+ #
448
+ # @yield [hooked_instance] Block for event hook action.
449
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
450
+ # Equivalent to parameter for #included and #extended.
451
+ #
452
+ # @return [Integer] Index after inserts.
453
+ #
454
+ def include_at_index( index, cluster_name, contexts, cascade_to, explicit_set = false, *modules, & block )
455
+
456
+ modules.each do |this_module|
457
+
458
+ should_insert = true
459
+
460
+ if @include_modules.has_key?( this_module )
461
+
462
+ if explicit_set
463
+ # if we have an existing index, insert at this one instead
464
+ existing_index = @stack.index { |this_frame | this_frame.action == :include and
465
+ this_frame.module == this_module }
466
+ @stack.delete_at( existing_index )
467
+ if existing_index < index
468
+ index -= 1
469
+ end
470
+ else
471
+ should_insert = false
472
+ end
473
+
474
+ end
475
+
476
+ if should_insert
477
+ this_stack_frame = self.class::FrameStruct.new( @instance,
478
+ cluster_name,
479
+ contexts ? contexts.empty? ? nil : contexts.dup : nil,
480
+ cascade_to ? cascade_to.empty? ? nil : cascade_to.dup : nil,
481
+ block,
482
+ this_module,
483
+ :include )
484
+ @stack.insert( index, this_stack_frame )
485
+ unless index < 0
486
+ index += 1
487
+ end
488
+ @include_modules[ this_module ] = true
489
+ end
490
+
491
+ end
492
+
493
+ return index
494
+
495
+ end
496
+
497
+ #####################
498
+ # extend_at_index #
499
+ #####################
500
+
501
+ ###
502
+ # @private
503
+ #
504
+ # Used by ChainProxy to insert modules before/after other modules.
505
+ #
506
+ # @param index Index where extend should occur.
507
+ #
508
+ # @param cluster_name Name of cluster for which extend event is to occur.
509
+ #
510
+ # @param contexts Contexts for which event hooks should occur.
511
+ #
512
+ # @param cascade_to Contexts for which event hooks should cascade.
513
+ #
514
+ # @param explicit_set Whether insert is an implicit position or an explicitly requested position.
515
+ #
516
+ # @param modules Modules to extend.
517
+ #
518
+ # @yield [hooked_instance] Block for event hook action.
519
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
520
+ # Equivalent to parameter for #extendd and #extended.
521
+ #
522
+ # @return [Integer] Index after inserts.
523
+ #
524
+ def extend_at_index( index, cluster_name, contexts, cascade_to, explicit_set = false, *modules, & block )
525
+
526
+ modules.each do |this_module|
527
+
528
+ should_insert = true
529
+
530
+ if @extend_modules.has_key?( this_module )
531
+
532
+ if explicit_set
533
+ # if we have an existing index, insert at this one instead
534
+ existing_index = @stack.index { |this_frame | this_frame.action == :extend and
535
+ this_frame.module == this_module }
536
+ @stack.delete_at( existing_index )
537
+ if index > 0 and existing_index < index
538
+ index -= 1
539
+ end
540
+ else
541
+ should_insert = false
542
+ end
543
+
544
+ end
545
+
546
+ if should_insert
547
+ this_stack_frame = self.class::FrameStruct.new( @instance,
548
+ cluster_name,
549
+ contexts ? contexts.empty? ? nil : contexts.dup : nil,
550
+ cascade_to ? cascade_to.empty? ? nil : cascade_to.dup : nil,
551
+ block,
552
+ this_module,
553
+ :extend )
554
+ @stack.insert( index, this_stack_frame )
555
+ unless index < 0
556
+ index += 1
557
+ end
558
+ @extend_modules[ this_module ] = true
559
+ end
560
+
561
+ end
562
+
563
+ return index
564
+
565
+ end
566
+
567
+ #################################
568
+ # include_and_extend_at_index #
569
+ #################################
570
+
571
+ ###
572
+ # @private
573
+ #
574
+ # Used by ChainProxy to insert modules before/after other modules.
575
+ #
576
+ # @param index Index where include and extend should occur.
577
+ #
578
+ # @param cluster_name Name of cluster for which include and extend event is to occur.
579
+ #
580
+ # @param contexts Contexts for which event hooks should occur.
581
+ #
582
+ # @param cascade_to Contexts for which event hooks should cascade.
583
+ #
584
+ # @param explicit_set Whether insert is an implicit position or an explicitly requested position.
585
+ #
586
+ # @param modules Modules to include and extend.
587
+ #
588
+ # @yield [hooked_instance] Block for event hook action.
589
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
590
+ # Equivalent to parameter for #include and extendd and #extended.
591
+ #
592
+ # @return [Integer] Index after inserts.
593
+ #
594
+ def include_and_extend_at_index( index, cluster_name, contexts, cascade_to, explicit_set = false, *modules, & block )
595
+
596
+ modules.each do |this_module|
597
+ index = include_at_index( index, cluster_name, contexts, cascade_to, explicit_set, this_module, & block )
598
+ index = extend_at_index( index, cluster_name, contexts, cascade_to, explicit_set, this_module, & block )
599
+ end
600
+
601
+ return index
602
+
603
+ end
604
+
605
+ #################################
606
+ # extend_and_include_at_index #
607
+ #################################
608
+
609
+ ###
610
+ # @private
611
+ #
612
+ # Used by ChainProxy to insert modules before/after other modules.
613
+ #
614
+ # @param index Index where extend and include and extend should occur.
615
+ #
616
+ # @param cluster_name Name of cluster for which extend and include and extend event is to occur.
617
+ #
618
+ # @param contexts Contexts for which event hooks should occur.
619
+ #
620
+ # @param cascade_to Contexts for which event hooks should cascade.
621
+ #
622
+ # @param explicit_set Whether insert is an implicit position or an explicitly requested position.
623
+ #
624
+ # @param modules Modules to extend and include.
625
+ #
626
+ # @yield [hooked_instance] Block for event hook action.
627
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
628
+ # Equivalent to parameter for #extend and include and extendd and #extended.
629
+ #
630
+ # @return [Integer] Index after inserts.
631
+ #
632
+ def extend_and_include_at_index( index, cluster_name, contexts, cascade_to, explicit_set = false, *modules, & block )
633
+
634
+ modules.each do |this_module|
635
+ extend_at_index( index, cluster_name, contexts, cascade_to, explicit_set, this_module, & block )
636
+ include_at_index( index, cluster_name, contexts, cascade_to, explicit_set, this_module, & block )
637
+ end
638
+
639
+ return self
640
+
641
+ end
642
+
643
+ #####################
644
+ # action_at_index #
645
+ #####################
646
+
647
+ ###
648
+ # @private
649
+ #
650
+ # Used by ChainProxy to insert modules before/after other modules.
651
+ #
652
+ # @param index Index where include should occur.
653
+ #
654
+ # @param cluster_name Name of cluster for which include event is to occur.
655
+ #
656
+ # @param contexts Contexts for which event hooks should occur.
657
+ #
658
+ # @param cascade_to Contexts for which event hooks should cascade.
659
+ #
660
+ # @param explicit_set Whether insert is an implicit position or an explicitly requested position.
661
+ #
662
+ # @yield [hooked_instance] Block for event hook action.
663
+ # @yieldparam hooked_instance Instance for which event hook is occurring.
664
+ # Equivalent to parameter for #included and #extended.
665
+ #
666
+ # @return [Integer] Index after inserts.
667
+ #
668
+ def action_at_index( index, cluster_name, contexts, cascade_to, explicit_set = false, & block )
669
+
670
+ new_frame = self.class::FrameStruct.new( @instance, cluster_name, contexts, cascade_to, block )
671
+
672
+ @stack.insert( index, new_frame )
673
+
674
+ unless index < 0
675
+ index += 1
676
+ end
677
+
678
+ return index
679
+
680
+ end
681
+
682
+ #################
683
+ # chain_proxy #
684
+ #################
685
+
686
+ ###
687
+ # @private
688
+ #
689
+ # Get Chain Proxy instance used by this Hook Controller.
690
+ #
691
+ # @return [Module::Cluster::InstanceController::HookController::ChainProxy] Chain Proxy instance.
692
+ #
693
+ def chain_proxy
694
+
695
+ @chain_proxy ||= self.class::ChainProxy.new( self )
696
+
697
+ return @chain_proxy.reset_state
698
+
699
+ end
700
+
701
+ ##################
702
+ # lowest_index #
703
+ ##################
704
+
705
+ ###
706
+ # @private
707
+ #
708
+ # Determine the lowest index for provided module(s).
709
+ #
710
+ # @overload lowest_index( include_or_extend, module, ... )
711
+ #
712
+ # @param include_or_extend :include, :extend or :include_and_extend
713
+ #
714
+ # @param module Modules for which lowest-index is being determined.
715
+ #
716
+ # @return [Integer] Lowest index.
717
+ #
718
+ def lowest_index( include_or_extend, *modules )
719
+
720
+ return indexes( include_or_extend, *modules )[ 0 ]
721
+
722
+ end
723
+
724
+ ###################
725
+ # highest_index #
726
+ ###################
727
+
728
+ ###
729
+ # @private
730
+ #
731
+ # Determine the highest index for provided module(s).
732
+ #
733
+ # @overload highest_index( include_or_extend, module, ... )
734
+ #
735
+ # @param include_or_extend :include, :extend or :include_and_extend
736
+ #
737
+ # @param module Modules for which highest-index is being determined.
738
+ #
739
+ # @return [Integer] Highest index.
740
+ #
741
+ def highest_index( include_or_extend, *modules )
742
+
743
+ return indexes( include_or_extend, *modules )[ -1 ]
744
+
745
+ end
746
+
747
+ ######################################################################################################################
748
+ private ##########################################################################################################
749
+ ######################################################################################################################
750
+
751
+ #############
752
+ # indexes #
753
+ #############
754
+
755
+ ###
756
+ # @private
757
+ #
758
+ # Get indexes for provided module(s).
759
+ #
760
+ # @overload indexes( include_or_extend, module, ... )
761
+ #
762
+ # @param include_or_extend :include, :extend or :include_and_extend
763
+ #
764
+ # @param module Modules for which indexes are being determined.
765
+ #
766
+ # @return [Array<Integer>] Indexes for modules in stack.
767
+ #
768
+ def indexes( include_or_extend, *modules )
769
+
770
+ indexes = [ ]
771
+
772
+ proc = nil
773
+
774
+ modules.each do |this_module|
775
+
776
+ case include_or_extend
777
+ when :include
778
+
779
+ this_index = @stack.index do |this_stack_frame|
780
+ this_stack_frame.action == :include and
781
+ this_stack_frame.module == this_module
782
+ end
783
+
784
+ when :extend
785
+ this_index = @stack.index do |this_stack_frame|
786
+ this_stack_frame.action == :extend and
787
+ this_stack_frame.module == this_module
788
+ end
789
+ when :include_or_extend
790
+ matched_action = nil
791
+ this_index = @stack.index do |this_stack_frame|
792
+ if this_stack_frame.action == :extend || this_stack_frame.action == :include and
793
+ this_stack_frame.module == this_module
794
+ matched_action = this_stack_frame.action
795
+ true
796
+ end
797
+ end
798
+ if this_index
799
+ match_action = nil
800
+ case matched_action
801
+ when :include
802
+ match_action = :extend
803
+ when :extend
804
+ match_action = :include
805
+ end
806
+ # if we matched include or extend look for the other one from the other side
807
+ second_index = @stack.rindex do |this_stack_frame|
808
+ this_stack_frame.action == match_action and
809
+ this_stack_frame.module == this_module
810
+ end
811
+ if second_index and second_index != this_index
812
+ indexes.push( this_index )
813
+ this_index = second_index
814
+ end
815
+ end
816
+ end
817
+
818
+ unless this_index
819
+ raise ::Module::Cluster::Exception::ModuleNotInStack.new( self, this_module )
820
+ end
821
+
822
+ indexes.push( this_index )
823
+
824
+ end
825
+
826
+ return indexes.sort
827
+
828
+ end
829
+
830
+ end