class Peeek::Supervisor

Attributes

hooks[R]

@attribute [r] hooks @return [Peeek::Hooks] hooks that is registered to the supervisor

original_callbacks[R]

@attribute [r] original_callbacks @return [Hash<Object, Method>] original callbacks of objects that is

supervising

Public Class Methods

create_for_instance() click to toggle source

Create a supervisor for instance methods.

@return [Peeek::Supervisor] a supervisor for instance methods

# File lib/peeek/supervisor.rb, line 9
def self.create_for_instance
  new(:method_added)
end
create_for_singleton() click to toggle source

Create a supervisor for singleton methods.

@return [Peeek::Supervisor] a supervisor for singleton methods

# File lib/peeek/supervisor.rb, line 16
def self.create_for_singleton
  new(:singleton_method_added)
end
new(callback_name) click to toggle source

Initialize the supervisor.

@param [Symbol] callback_name name of the method that is called when

methods was added to object of a hook
# File lib/peeek/supervisor.rb, line 24
def initialize(callback_name)
  @callback_name = callback_name
  @hooks = Hooks.new
  @original_callbacks = {}
end

Public Instance Methods

<<(*hooks)
Alias for: add
add(*hooks) click to toggle source

Add hooks to target that is supervised.

@param [Array<Peeek::Hook>] hooks hooks that is supervised

# File lib/peeek/supervisor.rb, line 42
def add(*hooks)
  @hooks.push(*hooks)

  hooks.map(&:object).uniq.each do |object|
    @original_callbacks[object] = proceed(object) unless proceeded?(object)
  end

  self
end
Also aliased as: <<
circumvent(&process) click to toggle source

Run process while circumvent supervision.

@yield any process that wants to run while circumvent supervision

# File lib/peeek/supervisor.rb, line 63
def circumvent(&process)
  current_callbacks = @original_callbacks.keys.map do |object|
    [object, object.method(@callback_name)]
  end

  define_callbacks(@original_callbacks)

  begin
    @hooks.circumvent(&process)
  ensure
    define_callbacks(Hash[current_callbacks])
  end
end
clear() click to toggle source

Clear the hooks and the objects that is supervising.

# File lib/peeek/supervisor.rb, line 54
def clear
  @hooks.clear
  define_callbacks(@original_callbacks).clear
  self
end

Private Instance Methods

define_callback(object, &proc) click to toggle source
# File lib/peeek/supervisor.rb, line 108
def define_callback(object, &proc)
  singleton_class = class << object; self end
  singleton_class.__send__(:define_method, @callback_name, &proc)
end
define_callbacks(callbacks) click to toggle source
# File lib/peeek/supervisor.rb, line 113
def define_callbacks(callbacks)
  callbacks.each do |object, callback|
    define_callback(object, &callback)
  end
end
proceed(object) click to toggle source
# File lib/peeek/supervisor.rb, line 83
def proceed(object)
  supervisor = self
  hooks = @hooks
  original_callbacks = @original_callbacks

  object.method(@callback_name).tap do |original_callback|
    define_callback(object) do |method_name|
      hook = hooks.get(self, method_name)

      if hook
        hooks.delete(hook)

        unless hooks.get(self)
          original_callback = original_callbacks.delete(self)
          supervisor.__send__(:define_callback, self, &original_callback)
        end

        hook.link
      end

      original_callback[method_name]
    end
  end
end
proceeded?(object) click to toggle source
# File lib/peeek/supervisor.rb, line 79
def proceeded?(object)
  !!@original_callbacks[object]
end