Module: Lolita::Hooks::ClassMethods
- Defined in:
- lib/lolita/hooks.rb
Instance Method Summary collapse
-
#add_hook(*names) ⇒ Object
This method is used to add hooks for class.
- #add_hooks(*names) ⇒ Object
- #all_hooks ⇒ Object
-
#clear_hooks ⇒ Object
Reset all hooks and callbacks to defaults.
- #collect_callbacks_from(name, const_name, scope_callbacks) ⇒ Object
-
#has_hook?(name) ⇒ Boolean
Is hook with name is defined for class.
-
#hooks ⇒ Object
All hooks for class.
- #hooks_scope ⇒ Object
- #hooks_scope=(value) ⇒ Object
- #in_hooks_scope(scope) ⇒ Object
-
#method_missing(*args, &block) ⇒ Object
Try to recognize named run methods like MyClass.run_after_save # will call MyClass.run(:after_save).
-
#recognize_hook_methods(method_name, *args, &block) ⇒ Object
Set #method_missing.
-
#register_callback(name, *methods, &block) ⇒ Object
Register callback with given scope.
-
#register_hook(name) ⇒ Object
Register hook for scope.
-
#run(hook_name, *args, &block) ⇒ Object
run is used to execute callback.
- #superclasses ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(*args, &block) ⇒ Object
Try to recognize named run methods like
MyClass.run_after_save # will call MyClass.run(:after_save)
330 331 332 333 334 |
# File 'lib/lolita/hooks.rb', line 330 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
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# 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) ⇒ Object
274 275 276 |
# File 'lib/lolita/hooks.rb', line 274 def add_hooks *names add_hook *names end |
#all_hooks ⇒ Object
257 258 259 260 261 262 263 264 265 266 |
# 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 ⇒ Object
Reset all hooks and callbacks to defaults.
269 270 271 272 |
# File 'lib/lolita/hooks.rb', line 269 def clear_hooks @hooks=[] @callbacks={} end |
#collect_callbacks_from(name, const_name, scope_callbacks) ⇒ Object
344 345 346 347 348 349 350 |
# 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) ⇒ Boolean
Is hook with name is defined for class.
324 325 326 |
# File 'lib/lolita/hooks.rb', line 324 def has_hook?(name) self.all_hooks.include?(name.to_sym) end |
#hooks ⇒ Object
All hooks for class. This is Array of hook names.
252 253 254 255 |
# File 'lib/lolita/hooks.rb', line 252 def hooks @hooks||=[] @hooks end |
#hooks_scope ⇒ Object
248 249 250 |
# File 'lib/lolita/hooks.rb', line 248 def hooks_scope @hooks_scope || self end |
#hooks_scope=(value) ⇒ Object
244 245 246 |
# File 'lib/lolita/hooks.rb', line 244 def hooks_scope=(value) @hooks_scope = value end |
#in_hooks_scope(scope) ⇒ Object
300 301 302 303 304 305 306 307 |
# 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 |
#recognize_hook_methods(method_name, *args, &block) ⇒ Object
Set #method_missing
337 338 339 340 341 342 |
# 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) ⇒ Object
Register callback with given scope.
353 354 355 356 357 358 359 360 |
# 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) ⇒ Object
Register hook for scope.
363 364 365 |
# File 'lib/lolita/hooks.rb', line 363 def register_hook(name) self.hooks<<name end |
#run(hook_name, *args, &block) ⇒ Object
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.
315 316 317 318 319 320 321 |
# File 'lib/lolita/hooks.rb', line 315 def run(hook_name,*args,&block) =args ? args. : {} 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,) runner.run(&block) end |
#superclasses ⇒ Object
367 368 369 370 371 372 373 374 375 376 377 |
# 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 |