Module: HaveAPI::Hooks
- Defined in:
- lib/haveapi/hooks.rb
Overview
All registered hooks and connected endpoints are stored in this module.
It supports connecting to both class and instance level hooks. Instance level hooks inherit all class registered hooks, but it is possible to connect to a specific instance and not for all instances of a class.
Usage
Register hooks
class MyClass include Hookable
has_hook :myhook
end
Class level hooks
Connect hook
MyClass.connect_hook(:myhook) do |ret, a, b, c| # a = 1, b = 2, c = 3 puts "Class hook!" ret end
# Call hooks
MyClass.call_hooks(:myhook, args: [1, 2, 3])
Instance level hooks
Create an instance of MyClass
my = MyClass.new
# Connect hook
my.connect_hook(:myhook) do |ret, a, b, c|
# a = 1, b = 2, c = 3
puts "Instance hook!"
ret
end
# Call instance hooks
my.call_instance_hooks_for(:myhook, args: [1, 2, 3])
# Call class hooks
my.call_class_hooks_for(:myhook, args: [1, 2, 3])
# Call both instance and class hooks at once
my.call_hooks_for(:myhook, args: [1, 2, 3])
Class Method Summary collapse
-
.call_for(klass, name, where = nil, args: [], initial: {}) ⇒ Object
Call all blocks that are connected to hook in
klasswithname. -
.connect_hook(klass, name, &block) ⇒ Object
Connect class hook defined in
klasswithnametoblock. -
.connect_instance_hook(klass, name, &block) ⇒ Object
Connect instance hook from instance
klasswithnametoblock. - .hook_classify(klass) ⇒ Object
-
.register_hook(klass, name) ⇒ Object
Register a hook defined by
klasswithname. - .stop(ret) ⇒ Object
Class Method Details
.call_for(klass, name, where = nil, args: [], initial: {}) ⇒ Object
Call all blocks that are connected to hook in klass with name.
klass may be a class name or an object instance.
If where is set, the blocks are executed in it with instance_exec.
args is an array of arguments given to all blocks. The first argument
to all block is always a return value from previous block or initial,
which defaults to an empty hash.
Blocks are executed one by one in the order they were connected. Blocks must return a hash, that is then passed to the next block and the return value from the last block is returned to the caller.
A block may decide that no further blocks should be executed. In such a case it calls Hooks.stop with the return value. It is then returned to the caller immediately.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/haveapi/hooks.rb', line 90 def self.call_for(klass, name, where = nil, args: [], initial: {}) classified = hook_classify(klass) catch(:stop) do return initial unless @hooks[classified] hooks = @hooks[classified][name] return initial unless hooks hooks.each do |hook| if where ret = where.instance_exec(initial, *args, &hook) else ret = hook.call(initial, *args) end initial.update(ret) if ret end initial end end |
.connect_hook(klass, name, &block) ⇒ Object
Connect class hook defined in klass with name to block.
klass is a class name.
59 60 61 |
# File 'lib/haveapi/hooks.rb', line 59 def self.connect_hook(klass, name, &block) @hooks[hook_classify(klass)][name] << block end |
.connect_instance_hook(klass, name, &block) ⇒ Object
Connect instance hook from instance klass with name to block.
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/haveapi/hooks.rb', line 64 def self.connect_instance_hook(klass, name, &block) unless @hooks[klass] @hooks[klass] = {} @hooks[klass.class].each do |k, v| @hooks[klass][k] = [] end end @hooks[klass][name] << block end |
.hook_classify(klass) ⇒ Object
112 113 114 |
# File 'lib/haveapi/hooks.rb', line 112 def self.hook_classify(klass) klass.is_a?(String) ? Object.const_get(klass) : klass end |
.register_hook(klass, name) ⇒ Object
Register a hook defined by klass with name.
klass is an instance of Class, that is class name, not it's instance.
49 50 51 52 53 54 55 |
# File 'lib/haveapi/hooks.rb', line 49 def self.register_hook(klass, name) classified = hook_classify(klass) @hooks ||= {} @hooks[classified] ||= {} @hooks[classified][name] = [] end |
.stop(ret) ⇒ Object
116 117 118 |
# File 'lib/haveapi/hooks.rb', line 116 def self.stop(ret) throw(ret) end |