Module: Lolita::Hooks::ClassMethods

Defined in:
lib/lolita/hooks.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args, &block) ⇒ Object

Try to recognize named fire methods like

MyClass.fire_after_save # will call MyClass.fire(:after_save)


174
175
176
177
178
# File 'lib/lolita/hooks.rb', line 174

def method_missing(*args, &block)
  unless self.recognize_hook_methods(*args,&block)
    super
  end
end

Instance Method Details

#add_hook(*names) ⇒ Object

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


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/lolita/hooks.rb', line 132

def add_hook(*names) 
  (names||[]).each{|hook_name|
    self.class_eval "      def self.\#{hook_name}(*methods,&block)\n        options=methods.extract_options!\n        in_hooks_scope(options[:scope]) do\n          register_callback(:\"\#{hook_name}\",*methods,&block)\n        end\n      end\n\n      def \#{hook_name}(*method,&block)\n        self.class.\#{hook_name}(*method,:scope=>self,&block)\n      end\n    HOOK\n    register_hook(hook_name)\n  }\nend\n",__FILE__,__LINE__+1

#clear_hooksObject

Reset all hooks and callbacks to defaults.



123
124
125
126
# File 'lib/lolita/hooks.rb', line 123

def clear_hooks
  @hooks=[]
  @callbacks={}
end

#fire(*hook_names, &block) ⇒ Object

Fire 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.fire(:before_save,:after_save,:scope=>MyClass.new)
# this will call callbacks in MyClass instance scope, that means that self will be MyClass instance.


156
157
158
159
160
161
162
163
164
165
# File 'lib/lolita/hooks.rb', line 156

def fire(*hook_names,&block)
  options=hook_names.extract_options!
  (hook_names || []).each do |hook_name|
    raise Lolita::HookNotFound, "Hook #{hook_name} is not defined for #{self}." unless self.has_hook?(hook_name)
    in_hooks_scope(options[:scope]) do
      callback=get_callback(hook_name)
      run_callback(callback,&block)
    end
  end
end

#given_callback_contentObject

Callback content is used to let callback content executed insede of fire block.



112
113
114
# File 'lib/lolita/hooks.rb', line 112

def given_callback_content
  @given_callback_content
end

#given_callback_content=(content) ⇒ Object

Setter for #callback_content



107
108
109
# File 'lib/lolita/hooks.rb', line 107

def given_callback_content=(content)
  @given_callback_content=content
end

#has_hook?(name) ⇒ Boolean

Is hook with name is defined for class.

Returns:

  • (Boolean)


168
169
170
# File 'lib/lolita/hooks.rb', line 168

def has_hook?(name)
  self.hooks.include?(name.to_sym)
end

#hooksObject

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



117
118
119
120
# File 'lib/lolita/hooks.rb', line 117

def hooks
  @hooks||=[]
  @hooks
end

#hooks_scopeObject

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



102
103
104
# File 'lib/lolita/hooks.rb', line 102

def hooks_scope
  @hooks_scope||self
end

#hooks_scope=(object) ⇒ Object

Setter for #hook_scope.



97
98
99
# File 'lib/lolita/hooks.rb', line 97

def hooks_scope=(object)
  @hooks_scope=object
end

#let_contentObject

Call callback block inside of fire block.

Example

MyClass.fire(:before_save) do 
   do_stuff
   let_content # execute callback block(-s) in same scope as fire is executed.
end


186
187
188
189
190
# File 'lib/lolita/hooks.rb', line 186

def let_content
  if content=self.given_callback_content
    run_block(self.given_callback_content)
  end
end

#recognize_hook_methods(method_name, *args, &block) ⇒ Object

Set #method_missing



193
194
195
196
197
198
# File 'lib/lolita/hooks.rb', line 193

def recognize_hook_methods method_name, *args, &block
  if method_name.to_s.match(/^fire_(\w+)/)
    self.fire($1,&block)
    true
  end
end