Module: Hooks

Overview

Module responsive of adding the Hook functionality to a class and its childs

How to use it:

# 1. Include the Hooks module to your class so exec_hooks become visible (and it's possible to register a hook)
include Hooks

# 2. Make a method that supports hooks
def my_method(params)
  exec_hooks(NameOfTheClass, :name_of_prehook, binding) # Not mandatory
  # do some stuff
  exec_hooks(NameOfTheClass, :name_of_posthook, binding) # Not mandatory
  return normal_return
rescue Hooks::ForceReturn => e
  return e.data # What the hooks forced to return
end

# 3. To register a hook call the function from Hooks
Hooks.register(NameOfTheClass, :name_of_the_hook, 'Reason so you can delete it') do |hook_binding|
  # Do something with self (object that called the hook) and hook_binding current binding
end

Defined Under Namespace

Modules: Reason Classes: ForceReturn

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(klass)

Function called when Hooks is included

Parameters:

  • klass (Class)

    klass receiving the hooks



106
107
108
# File 'scripts/00010 Hooks.rb', line 106

def included(klass)
  klass.instance_variable_set(:@__hooks, {})
end

.register(klass, name, reason = nil, &block) {|hook_binding| ... }

Function that register a hook

Parameters:

  • klass (Class)

    class containing the hook information

  • name (Symbol)

    name of the hook list

  • reason (String) (defaults to: nil)

    reason for the hook (so we can remove it)

  • block (Proc)

    actuall hook

Yields:

  • (hook_binding)

    hook called when requested

Yield Parameters:

  • hook_binding (Binding)

    binding from the calling method



76
77
78
79
80
81
82
83
84
# File 'scripts/00010 Hooks.rb', line 76

def register(klass, name, reason = nil, &block)
  log_error(format('A proc named %<name>s was defined without reason in %<class>s', name: name, class: klass)) unless reason
  hooks = (klass.instance_variable_get(:@__hooks)[name] ||= [])
  hooks << block
  block.extend(Reason)
  block.reason = reason || 'None'
rescue NoMethodError
  raise 'Hooks was not included to that class!'
end

.remove(klass, name, reason = 'None')

Function that removes a hook with a reason

Parameters:

  • klass (Class)

    class containing the hook information

  • name (Symbol)

    name of the hook list

  • reason (String) (defaults to: 'None')

    reason for the hook



90
91
92
93
# File 'scripts/00010 Hooks.rb', line 90

def remove(klass, name, reason = 'None')
  hooks = klass.instance_variable_get(:@__hooks)&.[](name)
  hooks&.reject! { |hook| hook.reason == reason }
end

.remove_without_name(klass, reason = 'None')

Function that removes a hook with a reason

Parameters:

  • klass (Class)

    class containing the hook information

  • reason (String) (defaults to: 'None')

    reason for the hook



98
99
100
101
102
# File 'scripts/00010 Hooks.rb', line 98

def remove_without_name(klass, reason = 'None')
  klass.instance_variable_get(:@__hooks)&.each_value do |hooks|
    hooks&.reject! { |hook| hook.reason == reason }
  end
end

Instance Method Details

#exec_hooks(klass, name, method_binding)

Function that execute the hooks

Parameters:

  • klass (Class)

    class containing the hook information

  • name (Symbol)

    name of the hook list

  • method_binding (Binding)

    binding of the method so the hook can modify locals

Raises:



52
53
54
55
56
57
58
59
# File 'scripts/00010 Hooks.rb', line 52

def exec_hooks(klass, name, method_binding)
  hooks = klass.instance_variable_get(:@__hooks)&.[](name)
  ForceReturn::CONST.hook_name = name
  hooks&.each do |hook|
    ForceReturn::CONST.reason = hook.reason
    instance_exec(method_binding, &hook)
  end
end

#force_return(object)

Function that force the return from the hook

Parameters:

  • object (Object)

    object to return

Raises:



63
64
65
66
# File 'scripts/00010 Hooks.rb', line 63

def force_return(object)
  ForceReturn::CONST.data = object
  raise ForceReturn::CONST
end