module Lolita::Hooks::ClassMethods

Public Instance Methods

add_hook(*names) click to toggle source

This method is used to add hooks for class. It accept one or more hook names.

Example

add_hook :before_save
MyClass.add_hooks :after_save, :around_save
# File lib/lolita/hooks.rb, line 282
      def add_hook(*names)
        (names||[]).each{|hook_name|
          self.class_eval <<-HOOK,__FILE__,__LINE__+1
            def self.#{hook_name}(*methods,&block)
              options=methods.extract_options!
              in_hooks_scope(options[:scope]) do
                register_callback(:"#{hook_name}",*methods,&block)
              end
            end

            def #{hook_name}(*method,&block)
              self.class.#{hook_name}(*method,:scope=>self,&block)
            end
          HOOK
          register_hook(hook_name)
        }
      end
add_hooks(*names) click to toggle source
# File lib/lolita/hooks.rb, line 274
def add_hooks *names
  add_hook *names
end
all_hooks() click to toggle source
# File lib/lolita/hooks.rb, line 257
def all_hooks
  @all_hooks||=self.ancestors.inject([]) do |result,const_name|
    if const_name.respond_to?(:hooks)
      result+=const_name.send(:hooks)
    else
      result
    end
  end
  @all_hooks
end
clear_hooks() click to toggle source

Reset all hooks and callbacks to defaults.

# File lib/lolita/hooks.rb, line 269
def clear_hooks
  @hooks=[]
  @callbacks={}
end
collect_callbacks_from(name,const_name,scope_callbacks) click to toggle source
# File lib/lolita/hooks.rb, line 344
def collect_callbacks_from(name,const_name,scope_callbacks)
    class_callbacks=const_name.callbacks[name.to_sym] || {}
    [:methods,:blocks].each do |attr|
      scope_callbacks[attr]=((class_callbacks[attr] || [])+(scope_callbacks[attr] || [])).uniq
    end
  scope_callbacks
end
has_hook?(name) click to toggle source

Is hook with name is defined for class.

# File lib/lolita/hooks.rb, line 324
def has_hook?(name)
  self.all_hooks.include?(name.to_sym)
end
hooks() click to toggle source

All hooks for class. This is Array of hook names.

# File lib/lolita/hooks.rb, line 252
def hooks
  @hooks||=[]
  @hooks
end
hooks_scope() click to toggle source
# File lib/lolita/hooks.rb, line 248
def hooks_scope
  @hooks_scope || self
end
hooks_scope=(value) click to toggle source
# File lib/lolita/hooks.rb, line 244
def hooks_scope=(value)
  @hooks_scope = value
end
in_hooks_scope(scope) { || ... } click to toggle source
# File lib/lolita/hooks.rb, line 300
def in_hooks_scope(scope)
  begin
    self.hooks_scope = scope
    yield
  ensure
    self.hooks_scope = self
  end
end
method_missing(*args, &block) click to toggle source

Try to recognize named run methods like

MyClass.run_after_save # will call MyClass.run(:after_save)
Calls superclass method
# File lib/lolita/hooks.rb, line 330
def method_missing(*args, &block)
  unless self.recognize_hook_methods(*args,&block)
    super
  end
end
recognize_hook_methods(method_name, *args, &block) click to toggle source

Set method_missing

# File lib/lolita/hooks.rb, line 337
def recognize_hook_methods method_name, *args, &block
  if method_name.to_s.match(/^run_(\w+)/)
    self.run($1,*args,&block)
    true
  end
end
register_callback(name,*methods,&block) click to toggle source

Register callback with given scope.

# File lib/lolita/hooks.rb, line 353
def register_callback(name,*methods,&block)
  temp_callback=hooks_scope.callbacks[name]||{}
  temp_callback[:methods]||=[]
  temp_callback[:methods]+=(methods||[]).compact
  temp_callback[:blocks]||=[]
  temp_callback[:blocks]<< block if block_given?
  hooks_scope.callbacks[name]=temp_callback
end
register_hook(name) click to toggle source

Register hook for scope.

# File lib/lolita/hooks.rb, line 363
def register_hook(name)
  self.hooks<<name
end
run(hook_name,*args,&block) click to toggle source

run is used to execute callback. Method accept one or more hook_names and optional block. It will raise error if hook don't exist for this class. Also it accept :scope options, that is used to get_callbacks and run_callbacks.

Example

MyClass.run(:before_save,:after_save,:scope=>MyClass.new)
# this will call callbacks in MyClass instance scope, that means that self will be MyClass instance.
# File lib/lolita/hooks.rb, line 315
def run(hook_name,*args,&block)

  options=args ? args.extract_options! : {}
  raise Lolita::HookNotFound, "Hook #{hook_name} is not defined for #{self}." unless self.has_hook?(hook_name)
  runner = Lolita::Hooks::Runner.new(self,hook_name,options)
  runner.run(&block)
end
superclasses() click to toggle source
# File lib/lolita/hooks.rb, line 367
def superclasses
  unless @klasses
    @klasses=[]
    self.ancestors.each do |const_name|
      if const_name.respond_to?(:hooks)
        @klasses<<const_name
      end
    end
  end
  @klasses
end