Module: Module::Cluster

Defined in:
lib/module/cluster.rb,
lib/module/namespaces.rb

Overview

Public interface to enable modules/classes with module-cluster capabilities.

Defined Under Namespace

Modules: Exception

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.cluster(instance, name) ⇒ ModuleCluster::Cluster::Cluster

Return cluster for instance or create if necessary

Parameters:

  • instance

    Instance for which cluster is being created.

  • name

    Name of cluster for instance.

Returns:

  • (ModuleCluster::Cluster::Cluster)

    Cluster instance.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/module/cluster.rb', line 93

def self.cluster( instance, name )

  unless instance_hash = @clusters[ instance ]
    @clusters[ instance ] = instance_hash = { }
  end
  
  name = name.to_sym
  
  unless cluster_instance = instance_hash[ name ]
    instance_hash[ name ] = cluster_instance = ::Module::Cluster::Cluster.new( instance, name )
  end
  
  return cluster_instance
  
end

.extended(instance) ⇒ Object

Ensures that instance controller exists for extended instance

and enables class or module support as appropriate.


24
25
26
27
28
29
30
31
32
33
# File 'lib/module/cluster.rb', line 24

def self.extended( instance )
  
  case instance
    when ::Class
      instance.extend( ::Module::Cluster::ClassSupport )
    when ::Module
      instance.extend( ::Module::Cluster::ModuleSupport )
  end
  
end

.has_cluster?(instance, name) ⇒ true, false

Return whether cluster exists for instance.

Parameters:

  • instance

    Instance for which cluster is being queried.

  • name

    Name of cluster for instance.

Returns:

  • (true, false)

    Whether cluster exists for instance.



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/module/cluster.rb', line 126

def self.has_cluster?( instance, name )
  
  has_cluster = false
  
  if instance_hash = @clusters[ instance ]
    has_cluster = instance_hash.has_key?( name.to_sym )
  end
  
  return has_cluster
  
end

.hook_cluster_events(instance, hooked_instance, event_context) ⇒ ModuleCluster::Cluster::InstanceController::HookController

Return instance controller for instance or create if necessary

Parameters:

  • instance

    Module cluster enabled instance for which hooks are being activated.

  • hooked_instance

    Iheriting instance for which events are being processed.

  • event_context

    Context for which event hooks are being processed.

Returns:

  • (ModuleCluster::Cluster::InstanceController::HookController)

    Hook Controller instance.



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/module/cluster.rb', line 233

def self.hook_cluster_events( instance, hooked_instance, event_context )

  requires_module_cluster_enable = false

  # Subclass hooks always cascade to the first subclass.
  # If it should casade for each subclass that has to be declared explicitly and will be handled below.
  unless event_context == :subclass
    instance_controller = instance_controller( instance )
    if instance_controller.instance_variable_defined?( :@subclass_controller )
      hooked_instance_controller = instance_controller( hooked_instance )
      hooked_instance_controller.subclass_controller.stack.concat( instance_controller.subclass_controller.stack )
      requires_module_cluster_enable = true
    end
  end

  hook_controller_for_context( instance, event_context ).stack.each do |this_frame|

    cascade_controller = event_context

    # test to see if this frame's cluster is disabled
    unless cluster( instance, this_frame.cluster ).disabled?
       
      should_cascade = false
      should_perform_action = nil
       
      # if we cascade we do that first - test to see if we should cascade into instance
      if cascade_context = this_frame.cascades

        if cascade_context.include?( :any )

          should_cascade = true
          should_perform_action = true
          
          case hooked_instance
            when ::Class
              cascade_controller = :subclass
          end

        else

          case hooked_instance
            when ::Class
              if event_context == :subclass
                if cascade_context.include?( :subclass )
                  should_cascade = true
                  should_perform_action = true
                end
              else
                has_subclass = cascade_context.include?( :subclass )
                has_class = cascade_context.include?( :class )
                if has_class and has_subclass
                  should_cascade = true
                  should_perform_action = true
                  cascade_controller = :subclass
                elsif has_class
                  should_cascade = true
                  should_perform_action = true
                elsif has_subclass
                  should_cascade = true
                  should_perform_action = false
                  cascade_controller = :subclass
                end
              end
            when ::Module
              if cascade_context.include?( :module )
                should_cascade = true
                should_perform_action = true
              elsif cascade_context.include?( :class ) or cascade_context.include?( :subclass )
                should_cascade = true
                should_perform_action = false
              end
          end

        end
        
        if should_cascade
          requires_module_cluster_enable = true
          hook_controller_for_context( hooked_instance, cascade_controller ).stack.push( this_frame )
        end

      end
      
      if cascade_context and ! cascade_context.empty?

        # already handled
      
      elsif match_context = this_frame.context and ! match_context.empty?

        # if we have a context we test against instance to see if we match, then we perform action
        case hooked_instance
          when ::Class
            if event_context == :subclass
              if match_context.include?( :subclass )
                should_perform_action = true
              end
            else
              if match_context.include?( :class )
                should_perform_action = true
              end
            end
          when ::Module
            if match_context.include?( :module )
              should_perform_action = true
            end
          else
            if match_context.include?( :instance )
              should_perform_action = true
            end
        end
        
      else

        # if we are supposed to cascade (and have no context) then we perform action
        # if we don't have a context then we perform action
        should_perform_action = true

      end

      if should_perform_action

        # if we have a module to include/extend
        if this_module = this_frame.module
          case this_action = this_frame.action
            when :include
              hooked_instance.module_eval do
                include this_module
              end
            when :extend
              hooked_instance.extend( this_module )
          end
        end

        # if we have a block it runs last
        if this_block = this_frame.block
          instance.module_exec( hooked_instance, this_frame.owner, & this_block )
        end

      end

    end

  end
  
  if requires_module_cluster_enable
    
    case hooked_instance
      when ::Class
        hooked_instance.extend( ::Module::Cluster::ClassSupport )
      when ::Module
        hooked_instance.extend( ::Module::Cluster::ModuleSupport )
    end
    
  end
  
end

.hook_controller_for_context(instance, event_context) ⇒ ModuleCluster::Cluster::InstanceController::HookController

Return instance controller for instance or create if necessary

Parameters:

  • instance

    Instance for which Hook Controller is being returned.

  • event_context

    Context for which event hooks are being processed.

Returns:

  • (ModuleCluster::Cluster::InstanceController::HookController)

    Hook Controller instance.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/module/cluster.rb', line 179

def self.hook_controller_for_context( instance, event_context )
  
  hook_stack = nil
  
  instance_controller = instance_controller( instance )
  
  case event_context
    
    when :before_include

      hook_stack = instance_controller.before_include_controller

    when :after_include

      hook_stack = instance_controller.after_include_controller

    when :before_extend

      hook_stack = instance_controller.before_extend_controller

    when :after_extend

      hook_stack = instance_controller.after_extend_controller

    when :subclass

      hook_stack = instance_controller.subclass_controller

  end
  
  return hook_stack
  
end

.instance_controller(instance) ⇒ ModuleCluster::Cluster::InstanceController

Return instance controller for instance or create if necessary

Parameters:

  • instance

    Instance for which instance controller is being created.

Returns:

  • (ModuleCluster::Cluster::InstanceController)

    Instance Controller instance.



152
153
154
155
156
157
158
159
160
# File 'lib/module/cluster.rb', line 152

def self.instance_controller( instance )
  
  unless instance_controller = @instances[ instance ]
    @instances[ instance ] = instance_controller = self::InstanceController.new( instance )
  end
  
  return instance_controller
  
end

Instance Method Details

#cluster(name) ⇒ Object

Get cluster for name. Will create cluster if it does not already exist.

Parameters:

  • name

    Name of cluster.



44
45
46
47
48
# File 'lib/module/cluster.rb', line 44

def cluster( name )
  
  return ::Module::Cluster.cluster( self, name )
  
end

#has_cluster?(name) ⇒ true, false

Get cluster for name. Will create cluster if it does not already exist.

Parameters:

  • name

    Name of cluster.

Returns:

  • (true, false)

    Whether cluster name exists for self.



61
62
63
64
65
# File 'lib/module/cluster.rb', line 61

def has_cluster?( name )
  
  return ::Module::Cluster.has_cluster?( self, name )
  
end