Module: Interloper::ClassMethods
- Defined in:
- lib/interloper.rb
Instance Method Summary collapse
- #after(*method_names, &callback) ⇒ Object
- #before(*method_names, &callback) ⇒ Object
- #generate_interloper_module ⇒ Object
-
#interloper_module ⇒ Object
Generates an Interloper module that is namespeced under the including class, if one does not already exist.
Instance Method Details
#after(*method_names, &callback) ⇒ Object
100 101 102 103 |
# File 'lib/interloper.rb', line 100 def after(*method_names, &callback) interloper_module.define_interloper_methods(*method_names) interloper_module.add_callbacks(:after, *method_names, &callback) end |
#before(*method_names, &callback) ⇒ Object
95 96 97 98 |
# File 'lib/interloper.rb', line 95 def before(*method_names, &callback) interloper_module.define_interloper_methods(*method_names) interloper_module.add_callbacks(:before, *method_names, &callback) end |
#generate_interloper_module ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/interloper.rb', line 28 def generate_interloper_module Module.new do class << self # @return [Array] The list of available hooks. def hooks [:before, :after] end # @return [Hash] The default hash for tracking callbacks to methods. def default_callbacks {}.tap do |callbacks| hooks.each do |hook| callbacks[hook] = {} end end end # @param [Symbol] hook Optional name of a hook. See .hook method in # this module. # @param [Symbol] method_name Optional name of a method. # @return [Hash, Array] A hash or array of callbacks. If the 'hook' # param is provided, it will return a hash of callbacks keyed by # method name. If both 'hook' and 'method_name' are provided, will # return an array of callbacks for the given hook and method. def callbacks(hook=nil, method_name=nil) @callbacks ||= default_callbacks if hook && method_name # Returns callback stack for a given method and hook. If there # aren't callbacks in the stack, return something enumberable to # be loop-friendly. @callbacks.fetch(hook).fetch(method_name, []) elsif hook # Return all callbacks for a given hook, e.g. :before. @callbacks.fetch(hook) else @callbacks end end def run_callbacks(hook, method_name, object_context, *orig_args, &orig_block) callbacks(hook, method_name).each do |callback| object_context.instance_exec *orig_args, &callback end end def add_callbacks(hook, *method_names, &callback) method_names.each do |method_name| callbacks[hook][method_name] ||= [] callbacks[hook][method_name] << callback end end def define_interloper_methods(*method_names) method_names.each do |method_name| define_method(method_name) do |*args, &block| called_method = __method__ interloper_module.run_callbacks(:before, called_method, self, *args, &block) return_val = super(*args,&block) interloper_module.run_callbacks(:after, called_method, self, *args, &block) return_val end end end end end end |
#interloper_module ⇒ Object
Generates an Interloper module that is namespeced under the including class, if one does not already exist. Then prepends the Interloper module to the including class.
20 21 22 23 24 25 26 |
# File 'lib/interloper.rb', line 20 def interloper_module # Create the Interloper module if it doesn't exist already const_set(:Interloper, generate_interloper_module) unless self.constants.include? :Interloper # Prepend the interloper module prepend const_get(:Interloper) const_get(:Interloper) end |