module Ducktape::Hookable

Public Class Methods

extended(_) click to toggle source
# File lib/ducktape/hookable.rb, line 24
def self.extended(_)
  raise 'Cannot extend, only include.'
end
included(base) click to toggle source
# File lib/ducktape/hookable.rb, line 3
def self.included(base)
  base.extend ClassMethods

  return if base.is_a?(Class)

  # Module

  # just create a proxy for #included
  include_method = if base.respond_to?(:included)
    base_included_method = base.method(:included)
    ->(c) do
      base_included_method.(c)
      c.send :include, ::Ducktape::Hookable
    end
  else
    ->(c) { c.send :include, ::Ducktape::Hookable }
  end

  base.define_singleton_method(:included, include_method)
end

Public Instance Methods

add_hook(event, hook = nil, &block) click to toggle source

Registers a block, a named method, or any object that responds to call to be triggered when the event occurs.

# File lib/ducktape/hookable.rb, line 104
def add_hook(event, hook = nil, &block)
  hook = block if block #block has precedence
  raise ArgumentError, 'no hook was passed' unless hook
  hook = hook.to_s unless hook.respond_to?(:call)
  hooks[event.to_s].unshift(hook)
  hook
end
clear_hooks(event = nil) click to toggle source

Removes all hooks from the specified event. If an event wasn’t passed, removes all hooks from all events.

# File lib/ducktape/hookable.rb, line 121
def clear_hooks(event = nil)
  if event
    hooks.delete(event.to_s) if hooks.has_key?(event.to_s)
    return
  end

  hooks.clear
  nil
end
on_changed(hook = nil, &block) click to toggle source

Generic event. It’s called for all triggered events.

# File lib/ducktape/hookable.rb, line 132
def on_changed(hook = nil, &block)
  add_hook __method__, hook, &block
end
remove_hook(event, hook) click to toggle source

Removes the specified hook. Returns nil if the hook wasn’t found.

# File lib/ducktape/hookable.rb, line 113
def remove_hook(event, hook)
  return unless hooks.has_key?(event.to_s)
  hook = hook.to_s unless hook.respond_to?(:call)
  hooks[event.to_s].delete(hook)
end