Class: Hanami::Utils::Callbacks::Chain

Inherits:
Object
  • Object
show all
Defined in:
gems/gems/hanami-utils-2.2.0.beta1/lib/hanami/utils/callbacks.rb

Overview

Series of callbacks to be executed

Since:

  • 0.1.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeHanami::Utils::Callbacks::Chain

Returns a new chain

Since:

  • 0.2.0

def initialize
  @chain = Concurrent::Array.new
end

Instance Attribute Details

#chainObject (readonly, protected)

Since:

  • 0.1.0

def chain
  @chain
end

Instance Method Details

#append(*callbacks, &block) ⇒ void

This method returns an undefined value.

Appends the given callbacks to the end of the chain.

Examples:

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

Parameters:

  • callbacks (Array)

    one or multiple callbacks to append

  • block (Proc)

    an optional block to be appended

Raises:

  • (RuntimeError)

    if the object was previously frozen

See Also:

Since:

  • 0.3.4

def append(*callbacks, &block)
  callables(callbacks, block).each do |c|
    @chain.push(c)
  end

  @chain.uniq!
end

#dupHanami::Utils::Callbacks

Return a duplicate callbacks chain

Returns:

Since:

  • 2.0.0

def dup
  super.tap do |instance|
    instance.instance_variable_set(:@chain, instance.chain.dup)
  end
end

#freezeObject

It freezes the object by preventing further modifications.

Examples:

require 'hanami/utils/callbacks'

chain = Hanami::Utils::Callbacks::Chain.new
chain.freeze

chain.frozen?  # => true

chain.append :authenticate! # => RuntimeError

See Also:

Since:

  • 0.2.0

def freeze
  super
  @chain.freeze
end

#prepend(*callbacks, &block) ⇒ void

This method returns an undefined value.

Prepends the given callbacks to the beginning of the chain.

Examples:

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

Parameters:

  • callbacks (Array)

    one or multiple callbacks to add

  • block (Proc)

    an optional block to be added

Raises:

  • (RuntimeError)

    if the object was previously frozen

See Also:

Since:

  • 0.3.4

def prepend(*callbacks, &block)
  callables(callbacks, block).each do |c|
    @chain.unshift(c)
  end

  @chain.uniq!
end

#run(context, *args) ⇒ Object

Runs all the callbacks in the chain. The only two ways to stop the execution are: raise or throw.

Examples:

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`.

Parameters:

  • context (Object)

    the context where we want the chain to be invoked.

  • args (Array)

    the arguments that we want to pass to each single callback.

Since:

  • 0.1.0

def run(context, *args)
  @chain.each do |callback|
    callback.call(context, *args)
  end
end