Module: SolidCallback::Core
- Defined in:
- lib/solid_callback/core.rb
Instance Method Summary collapse
-
#callback_applicable?(callback, method_name, instance) ⇒ Boolean
Check if a callback should be run for a method.
-
#callbacks_for(type) ⇒ Object
Get all callbacks of a specific type.
-
#evaluate_condition(condition, instance) ⇒ Object
Evaluate a condition (symbol method name, proc, or lambda).
-
#handle_method_added(method_name) ⇒ Object
Handle method_added hook.
-
#register_callback(type, callback_method, options = {}) ⇒ Object
Register a callback.
-
#wrap_method_with_callbacks(method_name) ⇒ Object
Wrap a method with callbacks.
Instance Method Details
#callback_applicable?(callback, method_name, instance) ⇒ Boolean
Check if a callback should be run for a method
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/solid_callback/core.rb', line 31 def callback_applicable?(callback, method_name, instance) # Check only/except constraints return false if callback[:except].include?(method_name) return false unless callback[:only] == [:all] || callback[:only].include?(method_name) # Check conditional constraints if callback[:if] condition = callback[:if] return false unless evaluate_condition(condition, instance) end if callback[:unless] condition = callback[:unless] return false if evaluate_condition(condition, instance) end true end |
#callbacks_for(type) ⇒ Object
Get all callbacks of a specific type
4 5 6 7 |
# File 'lib/solid_callback/core.rb', line 4 def callbacks_for(type) @_solid_callback_store ||= { before: {}, after: {}, around: {} } @_solid_callback_store[type] end |
#evaluate_condition(condition, instance) ⇒ Object
Evaluate a condition (symbol method name, proc, or lambda)
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/solid_callback/core.rb', line 51 def evaluate_condition(condition, instance) case condition when Symbol, String instance.send(condition) when Proc instance.instance_exec(&condition) else true end end |
#handle_method_added(method_name) ⇒ Object
Handle method_added hook
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/solid_callback/core.rb', line 63 def handle_method_added(method_name) # Skip if we're in the process of defining a wrapped method return if @_solid_callback_wrapping_method # Skip special methods and private/protected methods return if method_name.to_s.start_with?('_solid_callback_') return if private_method_defined?(method_name) || protected_method_defined?(method_name) wrap_method_with_callbacks(method_name) end |
#register_callback(type, callback_method, options = {}) ⇒ Object
Register a callback
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/solid_callback/core.rb', line 10 def register_callback(type, callback_method, = {}) # Make sure callback store exists @_solid_callback_store ||= { before: {}, after: {}, around: {} } # Normalize options only = Array([:only] || :all) except = Array([:except] || []) if_condition = [:if] unless_condition = [:unless] # Store the callback information @_solid_callback_store[type][callback_method] = { method: callback_method, only: only, except: except, if: if_condition, unless: unless_condition } end |
#wrap_method_with_callbacks(method_name) ⇒ Object
Wrap a method with callbacks
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/solid_callback/core.rb', line 75 def wrap_method_with_callbacks(method_name) return unless instance_methods(false).include?(method_name) @_solid_callback_wrapping_method = true # Create a reference to the original method alias_method "_solid_callback_original_#{method_name}", method_name # Redefine the method with callbacks define_method(method_name) do |*args, &block| run_callbacks(:before, method_name) # Execute around callbacks or the original method result = run_around_callbacks(method_name, args, block) run_callbacks(:after, method_name) result end @_solid_callback_wrapping_method = false end |