Module: Hook

Defined in:
lib/scout/misc/hook.rb

Class Method Summary collapse

Class Method Details

.apply(hook_class, base_class) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/scout/misc/hook.rb', line 6

def self.apply(hook_class, base_class)
  base_class.class_variable_set(:@@hooks, []) unless base_class.class_variables.include?([])
  base_class.class_variable_get(:@@hooks).push hook_class

  hook_class.singleton_methods.each do |method_name|
    next unless base_class.singleton_methods.include? method_name
    orig_name = ("orig_" + method_name.to_s).to_sym
    if not base_class.singleton_methods.include?(orig_name)
      base_class.singleton_class.alias_method orig_name, method_name
      base_class.define_singleton_method method_name do |*args|
        base_class.class_variable_get(:@@hooks).each do |hook|
          next if hook.respond_to?(:claim) and not hook.claim(*args)
          if hook.respond_to?(method_name)
            return hook.send(method_name, *args)
          end
        end
        return base_class.send(orig_name, *args)
      end
    end
  end

  hook_class.instance_methods.each do |method_name|
    next unless base_class.instance_methods.include? method_name
    orig_name = ("orig_" + method_name.to_s).to_sym
    if not base_class.instance_methods.include?(orig_name)
      base_class.alias_method orig_name, method_name
      base_class.define_method method_name do |*args|
        base_class.class_variable_get(:@@hooks).each do |hook|
          next if hook.respond_to?(:claim) and not hook.claim(self, *args)
          if hook.instance_methods.include?(method_name)
            return hook.instance_method(method_name).bind(self).call *args
            #return self.instance_exec *args, &hook.instance_method(method_name)
          end
        end
        return self.send(orig_name, *args)
      end
    end
  end
end

.extended(hook_class) ⇒ Object



2
3
4
# File 'lib/scout/misc/hook.rb', line 2

def self.extended(hook_class)
  hook_class.class_variable_set(:@@prev_methods, hook_class.methods)
end