Module: ContextR::ClassMethods

Includes:
MutexCode
Included in:
ContextR
Defined in:
lib/contextr/class_methods.rb

Overview

:nodoc:

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MutexCode

#is_blocked?, #only_once, #semaphore, #synchronized

Class Method Details

.extended(base) ⇒ Object



114
115
116
# File 'lib/contextr/class_methods.rb', line 114

def self.extended(base)
  base.instance_variable_set(:@layers, {})
end

Instance Method Details

#active_layers_as_classesObject



19
20
21
# File 'lib/contextr/class_methods.rb', line 19

def active_layers_as_classes
  Dynamic[:layers]
end

#call_methods_stack(stack, receiver, method_name, arguments, block) ⇒ Object



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
# File 'lib/contextr/class_methods.rb', line 39

def call_methods_stack(stack, receiver, method_name, arguments, block)
  if stack.size == 1
    stack.pop.call(*arguments, &block)
  else
    stack.pop.__send__(method_name, *arguments) do |action, *rest_args|
      case action
      when :receiver
        receiver
      when :block
        block
      when :block!
        block.call(*rest_args)
      when :block=
        block = rest_args.first
      when :block_given?
        !block.nil?
      when :next
        rest_args.shift unless method_name == :method_missing
        call_methods_stack(stack, receiver, method_name, rest_args, block)
      else 
        raise ArgumentError, "Use only :receiver, :block, :block_given?, " +
                             ":block!, :block=, or :next " +
                             "as first argument."
      end
    end
  end
end

#core_proxy(receiver, contextified_class, method_name) ⇒ Object



79
80
81
82
# File 'lib/contextr/class_methods.rb', line 79

def core_proxy(receiver, contextified_class, method_name)
  ContextR::stored_core_methods[contextified_class][
    method_name][:code].bind(receiver)
end

#layer_by_symbol(sym) ⇒ Object



35
36
37
# File 'lib/contextr/class_methods.rb', line 35

def layer_by_symbol(sym)
  @layers[sym] ||= ContextR::Layer.new
end

#layered_do(layers, block) ⇒ Object



23
24
25
# File 'lib/contextr/class_methods.rb', line 23

def layered_do(layers, block)
  Dynamic.let({:layers => layers}, &block)
end

#layers_as_classesObject



27
28
29
# File 'lib/contextr/class_methods.rb', line 27

def layers_as_classes
  @layers.values
end

#meta_method?(method_name) ⇒ Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/contextr/class_methods.rb', line 110

def meta_method?(method_name)
  method_name.to_s =~ /method_added(_with(out)?_contextr_listener)?/
end

#observe_core_method(klass, method_name, version) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/contextr/class_methods.rb', line 84

def observe_core_method(klass, method_name, version)
  only_once do
    klass.class_eval(%Q{
        if self.instance_methods.include?("#{method_name}")
          undef_method("#{method_name}")
        end
        def #{method_name}(*arguments, &block)
          ContextR::on_core_method_called(
            self,
            ObjectSpace._id2ref(#{klass.object_id}), 
            :#{method_name},
            arguments, block)
        end
      }, __FILE__, __LINE__) if save_core_method(klass, method_name, version)
  end
end

#on_core_method_called(receiver, contextified_class, method_name, arguments, block) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/contextr/class_methods.rb', line 67

def on_core_method_called(receiver, contextified_class, 
                          method_name, arguments, block)

  proxies = active_layers_as_classes.inject([]) do |array, layer|
    array << layer.context_proxy(contextified_class, method_name)
  end.compact
  proxies << core_proxy(receiver, contextified_class, method_name) 

  call_methods_stack(proxies.reverse, receiver, 
                     method_name, arguments, block)
end

#save_core_method(klass, method_name, version) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/contextr/class_methods.rb', line 101

def save_core_method(klass, method_name, version)
  if !meta_method?(method_name) and 
      (!stored_core_methods[klass].include?(method_name) or
          stored_core_methods[klass][method_name][:version] < version)
    stored_core_methods[klass][method_name] = 
      { :version => version, :code => klass.instance_method(method_name) }
  end
end

#stored_core_methodsObject



5
6
7
8
9
# File 'lib/contextr/class_methods.rb', line 5

def stored_core_methods
  @stored_core_methods ||= Hash.new do |hash, key|
    hash[key] = Hash.new
  end
end

#stored_module_definitionsObject



11
12
13
14
15
16
17
# File 'lib/contextr/class_methods.rb', line 11

def stored_module_definitions
  @stored_module_definitions ||= Hash.new do |layer_hash, layer|
    layer_hash[layer] = Hash.new do |extended_modules_hash, x_module|
      extended_modules_hash[x_module] = Module.new
    end
  end
end

#symbol_by_layer(lay) ⇒ Object



31
32
33
# File 'lib/contextr/class_methods.rb', line 31

def symbol_by_layer(lay)
  @layers.index(lay)
end