Module: HookR::Hooks
- Defined in:
- lib/hookr.rb
Overview
Include this module to decorate your class with hookable goodness.
Note: remember to call super() if you define your own self.inherited().
Defined Under Namespace
Modules: CallbackHelpers, ClassMethods
Class Method Summary collapse
-
.included(other) ⇒ Object
end of CallbackHelpers.
Instance Method Summary collapse
-
#add_listener(listener, handle = listener_to_handle(listener)) ⇒ Object
Add a listener object.
-
#execute_hook(hook_name, *args, &block) ⇒ Object
Execute all callbacks associated with the hook identified by
hook_name
, plus any wildcard callbacks. -
#hooks ⇒ Object
returns the hooks exposed by this object.
-
#remove_listener(handle_or_listener) ⇒ Object
Remove a listener by handle or by the listener object itself.
Class Method Details
.included(other) ⇒ Object
end of CallbackHelpers
182 183 184 185 186 187 |
# File 'lib/hookr.rb', line 182 def self.included(other) other.extend(ClassMethods) other.extend(CallbackHelpers) other.send(:include, CallbackHelpers) other.send(:define_hook, :__wildcard__) end |
Instance Method Details
#add_listener(listener, handle = listener_to_handle(listener)) ⇒ Object
Add a listener object. The object should have a method defined for every hook this object publishes.
230 231 232 233 234 |
# File 'lib/hookr.rb', line 230 def add_listener(listener, handle=listener_to_handle(listener)) add_wildcard_callback(handle) do |event| listener.send(event.name, *event.arguments) end end |
#execute_hook(hook_name, *args, &block) ⇒ Object
Execute all callbacks associated with the hook identified by hook_name
, plus any wildcard callbacks.
When a block is supplied, this method functions differently. In that case the callbacks are executed recursively. The most recently defined callback is executed and passed an event and a set of arguments. Calling event.next will pass execution to the next most recently added callback, which again will be passed an event with a reference to the next callback, and so on. When the list of callbacks are exhausted, the block
is executed as if it too were a callback. If at any point event.next is passed arguments, they will replace the value of the callback arguments for callbacks further down the chain.
In this way you can use callbacks as “around” advice to a block of code. For instance:
execute_hook(:write_data, data) do |data|
write(data)
end
Here, the code exposes a :write_data hook. Any callbacks attached to the hook will “wrap” the data writing event. Callbacks might log when the data writing operation was started and stopped, or they might encrypt the data before it is written, etc.
218 219 220 221 222 223 224 225 226 |
# File 'lib/hookr.rb', line 218 def execute_hook(hook_name, *args, &block) event = Event.new(self, hook_name, args, !!block) if block execute_hook_recursively(hook_name, event, block) else execute_hook_iteratively(hook_name, event) end end |
#hooks ⇒ Object
returns the hooks exposed by this object
190 191 192 |
# File 'lib/hookr.rb', line 190 def hooks fetch_or_create_hooks.dup.freeze end |
#remove_listener(handle_or_listener) ⇒ Object
Remove a listener by handle or by the listener object itself
237 238 239 240 241 242 243 |
# File 'lib/hookr.rb', line 237 def remove_listener(handle_or_listener) handle = case handle_or_listener when Symbol then handle_or_listener else listener_to_handle(handle_or_listener) end remove_wildcard_callback(handle) end |