class Hanami::Utils::Callbacks::Chain
Series of callbacks to be executed
@since 0.1.0 @private
Attributes
Public Class Methods
Returns a new chain
@return [Hanami::Utils::Callbacks::Chain]
@since 0.2.0
# File lib/hanami/utils/callbacks.rb, line 25 def initialize @chain = Concurrent::Array.new end
Public Instance Methods
Appends the given callbacks to the end of the chain.
@param callbacks [Array] one or multiple callbacks to append @param block [Proc] an optional block to be appended
@return [void]
@raise [RuntimeError] if the object was previously frozen
@see prepend
@see run
@see Hanami::Utils::Callbacks::Callback
@see Hanami::Utils::Callbacks::MethodCallback
@see Hanami::Utils::Callbacks::Chain#freeze
@since 0.3.4
@example
require 'hanami/utils/callbacks' chain = Hanami::Utils::Callbacks::Chain.new # Append a Proc to be used as a callback, it will be wrapped by `Callback` # The optional argument(s) correspond to the one passed when invoked the chain with `run`. chain.append { Authenticator.authenticate! } chain.append { |params| ArticleRepository.new.find(params[:id]) } # Append a Symbol as a reference to a method name that will be used as a callback. # It will wrapped by `MethodCallback` # If the #notificate method accepts some argument(s) they should be passed when `run` is invoked. chain.append :notificate
# File lib/hanami/utils/callbacks.rb, line 60 def append(*callbacks, &block) callables(callbacks, block).each do |c| @chain.push(c) end @chain.uniq! end
Return a duplicate callbacks chain
@return [Hanami::Utils::Callbacks] the duplicated chain
@since 2.0.0
# File lib/hanami/utils/callbacks.rb, line 163 def dup super.tap do |instance| instance.instance_variable_set(:@chain, instance.chain.dup) end end
It freezes the object by preventing further modifications.
@since 0.2.0
@see ruby-doc.org/core/Object.html#method-i-freeze
@example
require 'hanami/utils/callbacks' chain = Hanami::Utils::Callbacks::Chain.new chain.freeze chain.frozen? # => true chain.append :authenticate! # => RuntimeError
# File lib/hanami/utils/callbacks.rb, line 184 def freeze super @chain.freeze end
Prepends the given callbacks to the beginning of the chain.
@param callbacks [Array] one or multiple callbacks to add @param block [Proc] an optional block to be added
@return [void]
@raise [RuntimeError] if the object was previously frozen
@see append
@see run
@see Hanami::Utils::Callbacks::Callback
@see Hanami::Utils::Callbacks::MethodCallback
@see Hanami::Utils::Callbacks::Chain#freeze
@since 0.3.4
@example
require 'hanami/utils/callbacks' chain = Hanami::Utils::Callbacks::Chain.new # Add a Proc to be used as a callback, it will be wrapped by `Callback` # The optional argument(s) correspond to the one passed when invoked the chain with `run`. chain.prepend { Authenticator.authenticate! } chain.prepend { |params| ArticleRepository.new.find(params[:id]) } # Add a Symbol as a reference to a method name that will be used as a callback. # It will wrapped by `MethodCallback` # If the #notificate method accepts some argument(s) they should be passed when `run` is invoked. chain.prepend :notificate
# File lib/hanami/utils/callbacks.rb, line 99 def prepend(*callbacks, &block) callables(callbacks, block).each do |c| @chain.unshift(c) end @chain.uniq! end
Runs all the callbacks in the chain. The only two ways to stop the execution are: ‘raise` or `throw`.
@param context [Object] the context where we want the chain to be invoked. @param args [Array] the arguments that we want to pass to each single callback.
@since 0.1.0
@example
require 'hanami/utils/callbacks' class Action private def authenticate! end def set_article(params) end end action = Action.new params = Hash[id: 23] chain = Hanami::Utils::Callbacks::Chain.new chain.append :authenticate!, :set_article chain.run(action, params) # `params` will only be passed as #set_article argument, because it has an arity greater than zero chain = Hanami::Utils::Callbacks::Chain.new chain.append do # some authentication logic end chain.append do |params| # some other logic that requires `params` end chain.run(action, params) Those callbacks will be invoked within the context of `action`.
# File lib/hanami/utils/callbacks.rb, line 152 def run(context, *args) @chain.each do |callback| callback.call(context, *args) end end
Private Instance Methods
@api private
# File lib/hanami/utils/callbacks.rb, line 196 def callables(callbacks, block) callbacks.push(block) if block callbacks.map { |c| Factory.fabricate(c) } end