class Lolita::Hooks::Runner

Attributes

given_callback_content[RW]
hooks_run_scope[RW]
hooks_scope[W]

Public Class Methods

new(hook_class,hook_name, options) click to toggle source
# File lib/lolita/hooks.rb, line 91
def initialize(hook_class,hook_name, options)
  @hook_class = hook_class
  @hook_name = hook_name
  @options = options
  @options[:once] = @options[:once] == true ? @hook_class : @options[:once]
end
runned?(hook_object,hook_name) click to toggle source
# File lib/lolita/hooks.rb, line 77
def runned?(hook_object,hook_name)
  if hook_object.respond_to?(:hooks_runned)
    hook_object.hooks_runned.include?(hook_name)
  end
end
singleton_hook(hook_object,hook_name) click to toggle source
# File lib/lolita/hooks.rb, line 65
def singleton_hook(hook_object,hook_name)
  class << hook_object
    def hooks_runned(name=nil)
      @hooks_runned ||=[]
      @hooks_runned << name if name
      @hooks_runned
    end
  end

  hook_object.hooks_runned(hook_name)
end
singleton_hooks() click to toggle source
# File lib/lolita/hooks.rb, line 83
def singleton_hooks
  @singleton_hooks || {}
end

Public Instance Methods

hooks_scope() click to toggle source

Hooks scope is used to execute callbacks. By default it is class itself.

# File lib/lolita/hooks.rb, line 99
def hooks_scope
  @hooks_scope || @hook_class
end
let_content() click to toggle source

Call callback block inside of run block.

Example

MyClass.run(:before_save) do
   do_stuff
   let_content # execute callback block(-s) in same scope as run is executed.
end
# File lib/lolita/hooks.rb, line 121
def let_content
  if self.given_callback_content.respond_to?(:call)
    run_block(self.given_callback_content)
  elsif self.given_callback_content
    self.given_callback_content
  end
end
run(&block) click to toggle source
# File lib/lolita/hooks.rb, line 103
def run(&block)
  if !@options[:once] || (@options[:once] && !self.class.runned?(@options[:once],@hook_name))
    self.class.singleton_hook(@options[:once] || Object,@hook_name)
    result = nil
    in_hooks_scope(@options[:scope],@options[:run_scope]) do
      callback = get_callback(@hook_name)
      result = run_callback(callback,&block)
    end
    result
  end
end

Protected Instance Methods

get_callback(name) click to toggle source

Return all callbacks If scope is not class then it merge class callbacks with scope callbacks. That means that class callbacks always will be called before scope callbacks.

# File lib/lolita/hooks.rb, line 156
def get_callback(name)
  scope_callbacks = hooks_scope.callbacks[name.to_sym] || {}

  @hook_class.superclasses.each do |const_name|
    scope_callbacks = @hook_class.collect_callbacks_from(name,const_name,scope_callbacks)
  end
  scope_callbacks
end
in_hooks_scope(scope,run_scope=nil) { || ... } click to toggle source

Switch between self and given scope. Block will be executed with scope. And after that it will switch back to self.

# File lib/lolita/hooks.rb, line 133
def in_hooks_scope(scope,run_scope=nil)
  begin
    this = self
    self.hooks_scope=scope || @hook_class
    self.hooks_scope.define_singleton_method(:let_content) do
      this.let_content
    end
    if run_scope
      run_scope.define_singleton_method(:let_content) do
        this.let_content
      end
    end
    self.hooks_run_scope = run_scope || self.hooks_scope
    yield
  ensure
    self.hooks_scope = @hook_class
    self.hooks_run_scope = self.hooks_scope
  end
end
run_block(block, &given_block) click to toggle source

Run block in scope.

# File lib/lolita/hooks.rb, line 203
def run_block block, &given_block
  hooks_run_scope.instance_eval(&block)
end
run_blocks(blocks,&given_block) click to toggle source

Run blocks from blocks Array. Also it set given_callback_content if block is given, this will allow to call let_content. Each block is runned with run_block. After first run result of first block become given_callback_content, and when next block call let_content, this string will be returned for that block

# File lib/lolita/hooks.rb, line 185
def run_blocks blocks,&given_block
  result=""

  self.given_callback_content=block_given? ? given_block : nil

  if blocks && !blocks.empty?
    blocks.each do |block|
      result << (run_block(block,&given_block)).to_s
      self.given_callback_content=result
    end
  elsif block_given?
    self.given_callback_content=nil
    result << run_block(given_block).to_s
  end
  result
end
run_callback(callback,&block) click to toggle source

Run callback. Each callback is Hash with :methods Array and </i>:blocks</i> Array

# File lib/lolita/hooks.rb, line 166
def run_callback(callback,&block)
  method_results=run_methods(callback[:methods],&block)
  block_results=run_blocks(callback[:blocks],&block)
  method_results+block_results
end
run_methods(methods, &block) click to toggle source

Run methods from methods Array

# File lib/lolita/hooks.rb, line 173
def run_methods methods, &block
  result = ""
  (methods||[]).each do |method_name|
    result << (hooks_run_scope.__send__(method_name,&block)).to_s
  end
  result
end