class Runaround::Manager

Attributes

apply[R]
for_instances[R]
receiver[R]

Public Class Methods

new(receiver, apply: true, for_instances: false) click to toggle source
# File lib/runaround/manager.rb, line 9
def initialize(receiver, apply: true, for_instances: false)
  @receiver = receiver
  @apply = !!apply
  @for_instances = !!for_instances
end

Public Instance Methods

after(method, fifo: true, &block) click to toggle source
# File lib/runaround/manager.rb, line 20
def after(method, fifo: true, &block)
  prepare_callback(
    method: method, type: :after, fifo: fifo, &block)
end
around(method, fifo: false, &block) click to toggle source
# File lib/runaround/manager.rb, line 25
def around(method, fifo: false, &block)
  prepare_callback(
    method: method, type: :around, fifo: fifo, &block)
end
before(method, fifo: true, &block) click to toggle source
# File lib/runaround/manager.rb, line 15
def before(method, fifo: true, &block)
  prepare_callback(
    method: method, type: :before, fifo: fifo, &block)
end
callbacks(method) click to toggle source
# File lib/runaround/manager.rb, line 30
def callbacks(method)
  all = all_callbacks(method)
  blocks = all.dup.tap{ |h| h.delete(:around) }
  fibers = all[:around].map{ |b| Fiber.new(&b) }
  return blocks, fibers
end
import(other) click to toggle source
# File lib/runaround/manager.rb, line 43
def import(other)
  validate_manager!(other)
  other.to_h.each do |method, callbacks|
    callbacks.each do |type, list|
      list.each do |block|
        prepare_callback(
          method: method, type: type, fifo: true, &block)
      end
    end
  end
end
to_h() click to toggle source
# File lib/runaround/manager.rb, line 37
def to_h
  callback_hooks.keys.reduce({}) do |h, method|
    h[method] = copy_callback_map(method); h
  end
end

Private Instance Methods

all_callbacks(method) click to toggle source
# File lib/runaround/manager.rb, line 119
def all_callbacks(method)
  @all_callbacks ||= {}
  @all_callbacks[method] ||= { before: [], after: [], around: [] }
end
callback_hooks() click to toggle source
# File lib/runaround/manager.rb, line 115
def callback_hooks
  @callback_hooks ||= {}
end
copy_callback_map(method) click to toggle source
# File lib/runaround/manager.rb, line 109
def copy_callback_map(method)
  all_callbacks(method).reduce({}) do |map,(type,arr)|
    map[type] = arr.dup; map
  end
end
prepare_callback(method:, type:, fifo:, &block) click to toggle source
# File lib/runaround/manager.rb, line 57
def prepare_callback(method:, type:, fifo:, &block)
  validate_opts!(method, type, fifo, block)
  setup_callback_hook(method)
  list = all_callbacks(method)[type]
  fifo ? list << block : list.unshift(block)
  list.size
end
setup_callback_hook(method) click to toggle source
# File lib/runaround/manager.rb, line 65
def setup_callback_hook(method)
  return true if callback_hooks[method]
  callback_hooks[method] = CallbackHook.build_for(method, self)
  receiver.singleton_class.prepend(callback_hooks[method]) if apply
end
validate_block!(block) click to toggle source
# File lib/runaround/manager.rb, line 98
def validate_block!(block)
  return if block.is_a?(Proc)
  raise CallbackSetupError, "you must pass a block for the callback!"
end
validate_fifo!(fifo) click to toggle source
# File lib/runaround/manager.rb, line 92
def validate_fifo!(fifo)
  return if [true, false, nil].include?(fifo)
  msg = "fifo must be true, false, or nil; got #{fifo.inspect}"
  raise CallbackSetupError, msg
end
validate_manager!(manager) click to toggle source
# File lib/runaround/manager.rb, line 103
def validate_manager!(manager)
  return if manager.is_a?(self.class)
  msg = "expected a #{self.class}, got: #{manager.inspect}"
  raise CallbackSetupError, msg
end
validate_method!(method) click to toggle source
# File lib/runaround/manager.rb, line 78
def validate_method!(method)
  return if !for_instances && receiver.respond_to?(method)
  return if for_instances && receiver.method_defined?(method)
  msg = "the receiver does not respond to #{method.inspect}"
  raise CallbackSetupError, "#{msg} ==> receiver.inspect"
end
validate_opts!(method, type, fifo, block) click to toggle source
# File lib/runaround/manager.rb, line 71
def validate_opts!(method, type, fifo, block)
  validate_method!(method)
  validate_type!(type)
  validate_fifo!(fifo)
  validate_block!(block)
end
validate_type!(type) click to toggle source
# File lib/runaround/manager.rb, line 85
def validate_type!(type)
  return if [:before, :after, :around].include?(type)
  msg = "#{type.inspect} is not a valid callback type"
  msg += "; must be one of [:before, :after, :around]"
  raise CallbackSetupError, msg
end