class Lolita::Hooks::Runner
Attributes
Public Class Methods
# 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
# 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
# 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
# File lib/lolita/hooks.rb, line 83 def singleton_hooks @singleton_hooks || {} end
Public Instance Methods
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
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
# 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
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
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 in scope.
# File lib/lolita/hooks.rb, line 203 def run_block block, &given_block hooks_run_scope.instance_eval(&block) end
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. 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 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