Class: Crochet::Hook
- Inherits:
-
Object
- Object
- Crochet::Hook
- Defined in:
- lib/crochet.rb
Constant Summary collapse
- TYPE_SPECS =
Map symbols to their class- or instance-relevant methods
{ :instance => { :accessor => :instance_method, :definer => :define_method, :evaluator => :instance_exec }, :class => { :accessor => :method, :definer => :define_singleton_method, :evaluator => :class_exec } }
Instance Method Summary collapse
- #_attach(timing, destructive, method, method_type = :instance, &block) ⇒ Object
-
#destroy ⇒ Object
When ‘destroy` is called, it should restore all affected methods.
-
#initialize(klass, &block) ⇒ Hook
constructor
A new instance of Hook.
Constructor Details
#initialize(klass, &block) ⇒ Hook
Returns a new instance of Hook.
17 18 19 20 21 |
# File 'lib/crochet.rb', line 17 def initialize(klass, &block) @klass = klass @methods = [] self.instance_eval(&block) if block end |
Instance Method Details
#_attach(timing, destructive, method, method_type = :instance, &block) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/crochet.rb', line 22 def _attach(timing, destructive, method, method_type=:instance, &block) specs = TYPE_SPECS[method_type] # Capture the original method orig_method = @klass.method(specs[:accessor]).(method) # Redefine the method @klass.send(specs[:definer], method) do |*args| # Pass the original arguments "before" hook methods if timing == :before hook_result = self.send(specs[:evaluator], *args, &block) args = hook_result if destructive end # Call the original method and assign the result method_result = (method_type == :instance ? orig_method.bind(self) : orig_method).call(*args) # Pass method result, followed by the args it received, to "after" hook methods if timing == :after hook_result = self.send(specs[:evaluator], method_result, *args, &block) method_result = hook_result if destructive end # Finally, return the (optionally overridden) method result method_result end @methods << { :orig => orig_method, :name => method, :type => method_type } nil end |
#destroy ⇒ Object
When ‘destroy` is called, it should restore all affected methods
63 64 65 66 67 68 69 70 71 |
# File 'lib/crochet.rb', line 63 def destroy @methods.each do |method| specs = TYPE_SPECS[method[:type]] @klass.send(specs[:definer], method[:name]) do |*args| (method[:type] == :instance ? method[:orig].bind(self) : method[:orig]).call(*args) end end @methods = [] end |