Class: Kanal::Core::Hooks::HookStorage

Inherits:
Object
  • Object
show all
Includes:
Logging::Logger
Defined in:
lib/kanal/core/hooks/hook_storage.rb

Overview

Allows hooks registration, attaching to hooks, calling hooks with arguments

Instance Method Summary collapse

Methods included from Logging::Logger

#logger

Constructor Details

#initializeHookStorage

Returns a new instance of HookStorage.



15
16
17
# File 'lib/kanal/core/hooks/hook_storage.rb', line 15

def initialize
  @listeners = {}
end

Instance Method Details

#attach(name) { ... } ⇒ void

This method returns an undefined value.

Attaches block to a specific hook. You can learn about available hooks by looking into documentation of the specific libraries, using this class.

NOTE: about weird saving objects with methods instead of blocks see more info in Condition class, you will learn why (hint: LocalJumpError)

Examples:

Attaching to name changing hook, the next step after @see #call example

hook_storage.attach :name_changed do |old_name, new_name|
  # Here you do something with the provided arguments
end

Parameters:

  • name (Symbol)

    <description>

Yields:

  • block that will be executed upon calling hook it was registered to



92
93
94
95
96
97
98
99
# File 'lib/kanal/core/hooks/hook_storage.rb', line 92

def attach(name, &block)
  raise "You cannot listen to hook that does not exist! Hook in question: #{name}" unless hook_exists? name

  proc_to_lambda_object = Object.new
  proc_to_lambda_object.define_singleton_method(:hook_block, &block)

  @listeners[name].append proc_to_lambda_object
end

#call(name, *args) ⇒ void

This method returns an undefined value.

Calling hook with any arguments you want. Well, when you registered hooks you basically had in mind which arguments should be used when calling them

Examples:

Calling hook with arguments

# Considering names variables (old_name, new_name) are available when calling a hook
# This one will call the :name_changed hook with passed arguments.
# What does that mean? That possibly there is a listener attached to this hook
# @see #attach for next step of this example
hook_storage.call :name_changed, old_name, new_name

Parameters:

  • name (Symbol)

    <description>

  • args (Array)

    <description>



63
64
65
66
67
68
69
70
71
# File 'lib/kanal/core/hooks/hook_storage.rb', line 63

def call(name, *args)
  raise "Cannot call hook that is not registered: #{name}" unless hook_exists? name

  @listeners[name].each do |l|
    l.method(:hook_block).call(*args)
  end
rescue RuntimeError => e
  raise "There was a problem with calling hook #{name}. More info: #{e.full_message}"
end

#register(name) ⇒ void

This method returns an undefined value.

Registers hook in storage. All you need is name

TODO: think about requiring optional string about hook arguments? like register(:my_hook, “name, last_name”) or is it too weird and unneeded? I mean besides the documentation there is no way to learn which arguments are used in specific hook. Wondrous world of dynamic languages 🌈🦄

Examples:

Registering a hook

hook_storage.register(:my_hook) # That is all

Parameters:

  • name (Symbol)

    <description>



35
36
37
38
39
40
41
42
43
44
# File 'lib/kanal/core/hooks/hook_storage.rb', line 35

def register(name)
  if hook_exists? name
    logger.warn "Hook '#{name}' already exists"
    return
  end

  logger.debug "Registering hook '#{name}'"

  @listeners[name] = []
end