Module: ModuleCluster::CascadeFeatures

Defined in:
lib/module-cluster.rb,
lib/module-cluster/ModuleCluster/CascadeFeatures.rb

Defined Under Namespace

Classes: CascadeStruct, DependencyModule

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.cascade_features(class_or_module, cascade_struct) ⇒ Object

self.cascade_features #



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/module-cluster/ModuleCluster/CascadeFeatures.rb', line 111

def self.cascade_features( class_or_module, cascade_struct )

  class_or_module.module_eval do
    include( *cascade_struct.includes.reverse ) unless cascade_struct.includes.empty?
    extend( *cascade_struct.extends.reverse ) unless cascade_struct.extends.empty?
  end

  cascade_struct.cascades.each do |this_dependency_module, this_method_and_module_set|
    this_method_and_module_set.each do |this_method, this_module_set|
      this_dependency_module.perform_cascades( class_or_module, this_method, this_module_set )
    end
  end
  
end

.cascade_struct_for_set_stack(module_self, class_or_module, set_stack) ⇒ Object

self.cascade_struct_for_set_stack #



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/module-cluster/ModuleCluster/CascadeFeatures.rb', line 34

def self.cascade_struct_for_set_stack( module_self, class_or_module, set_stack )
  
  includes = Array.new
  extends = Array.new
  cascades = Hash.new
  
  set_stack.each do |this_set|
    
    if this_set.is_a?( ModuleCluster::ClusterStack::Block::Set )
      
      class_or_module.instance_eval do
        extend( ModuleCluster )
      end
      
      case this_set.runtime_block.arity
        when 0
          module_self.instance_eval( & this_set.runtime_block )
        else
          module_self.instance_exec( class_or_module, & this_set.runtime_block )
      end
      
    else
      
      # get cascades
      if this_set.dependency_module.should_cascade?( class_or_module )
        cascades[ this_set.dependency_module ] ||= Hash.new
        cascades[ this_set.dependency_module ][ this_set.method ] ||= Array.new
        cascades[ this_set.dependency_module ][ this_set.method ].concat( this_set.modules )            
      end

      # get runtime block
      runtime_set = nil
      if block = this_set.runtime_includes_or_extends_block
        runtime_set = ModuleCluster::CascadeFeatures.get_runtime_includes_or_extends_from_block( module_self, 
                                                                                                 class_or_module,
                                                                                                 this_set.include_or_extend,
                                                                                                 block )
        cascades[ this_set.dependency_module ] ||= Hash.new
        cascades[ this_set.dependency_module ][ this_set.method ] ||= Array.new
        cascades[ this_set.dependency_module ][ this_set.method ].concat( runtime_set )            
      end
      # get includes/extends
      case this_set.include_or_extend
        when :include
          this_set.modules.each do |this_module|
            if this_set.dependency_module.should_include_or_extend?( class_or_module )
              includes.concat( this_set.modules )            
            end
          end
          includes.concat( runtime_set ) if runtime_set
        when :extend
          if this_set.dependency_module.should_include_or_extend?( class_or_module )
            extends.concat( this_set.modules )
          end
          extends.concat( runtime_set ) if runtime_set
      end
    
    end
    
  end
  
  includes.uniq!
  extends.uniq!
  cascades.each do |this_dependency_module, this_method_and_module_set|
    this_method_and_module_set.each do |this_method, this_module_set|
      this_module_set.uniq!
    end
  end
      
  return ModuleCluster::CascadeFeatures::CascadeStruct.new( includes, extends, cascades )
  
end

.get_runtime_includes_or_extends_from_block(module_self, class_or_module, include_or_extend, runtime_includes_or_extends_block) ⇒ Object

self.get_runtime_includes_or_extends_from_block #



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/module-cluster/ModuleCluster/CascadeFeatures.rb', line 11

def self.get_runtime_includes_or_extends_from_block( module_self, class_or_module, include_or_extend, runtime_includes_or_extends_block )
  
  includes_or_extends = nil
  
  case runtime_includes_or_extends_block.arity
    when 0
      includes_or_extends = module_self.instance_eval( & runtime_includes_or_extends_block )
    else
      includes_or_extends = module_self.instance_exec( class_or_module, & runtime_includes_or_extends_block )
  end
  
  unless includes_or_extends.is_a?( Array )
    includes_or_extends = [ includes_or_extends ]
  end
  
  return includes_or_extends
  
end

Instance Method Details

#append_features(class_or_module) ⇒ Object

append_features #



130
131
132
133
134
135
136
137
# File 'lib/module-cluster/ModuleCluster/CascadeFeatures.rb', line 130

def append_features( class_or_module )
      
  cascade_struct = ModuleCluster::CascadeFeatures.cascade_struct_for_set_stack( self, class_or_module, cluster_stack.cascading_prepending_includes )
  ModuleCluster::CascadeFeatures.cascade_features( class_or_module, cascade_struct )
  
  super
  
end

#extend_object(class_or_module) ⇒ Object

extend_object #



156
157
158
159
160
161
162
163
# File 'lib/module-cluster/ModuleCluster/CascadeFeatures.rb', line 156

def extend_object( class_or_module )

  cascade_struct = ModuleCluster::CascadeFeatures.cascade_struct_for_set_stack( self, class_or_module, cluster_stack.cascading_prepending_extends )
  ModuleCluster::CascadeFeatures.cascade_features( class_or_module, cascade_struct )
  
  super
  
end

#extended(class_or_module) ⇒ Object

extended #



169
170
171
172
173
174
175
176
# File 'lib/module-cluster/ModuleCluster/CascadeFeatures.rb', line 169

def extended( class_or_module )

  super

  cascade_struct = ModuleCluster::CascadeFeatures.cascade_struct_for_set_stack( self, class_or_module, cluster_stack.cascading_extends )
  ModuleCluster::CascadeFeatures.cascade_features( class_or_module, cascade_struct )

end

#included(class_or_module) ⇒ Object

included #



143
144
145
146
147
148
149
150
# File 'lib/module-cluster/ModuleCluster/CascadeFeatures.rb', line 143

def included( class_or_module )

  super

  cascade_struct = ModuleCluster::CascadeFeatures.cascade_struct_for_set_stack( self, class_or_module, cluster_stack.cascading_includes )
  ModuleCluster::CascadeFeatures.cascade_features( class_or_module, cascade_struct )
  
end