module ActiveSupport::Callbacks

def halted_callback_hook(filter, name)

to provide better debugging/logging.
This can be overridden in ActiveSupport::Callbacks implementors in order
A hook invoked every time a before callback is halted.
def halted_callback_hook(filter, name)
end

def run_callbacks(kind)

as possible that we were here.
smoothly through and into the supplied block, we want as little evidence
callback can be as noisy as it likes -- but when control has passed
the visible call stack. An exception from inside a :before or :after
user code, it has an additional design goal of minimizing its impact on
As this method is used in many places, and often wraps large portions of

--

end
save
run_callbacks :save do

if callbacks have been set but no block is given.
result of the block, +nil+ if no callbacks have been set, or +true+
If the callback chain was halted, returns +false+. Otherwise returns the

order.
the block (if given one), and then runs the after callbacks in reverse
Calls the before and around callbacks in the order they were set, yields

Runs the callbacks for the given event.
def run_callbacks(kind)
  callbacks = __callbacks[kind.to_sym]
  if callbacks.empty?
    yield if block_given?
  else
    env = Filters::Environment.new(self, false, nil)
    next_sequence = callbacks.compile
    # Common case: no 'around' callbacks defined
    if next_sequence.final?
      next_sequence.invoke_before(env)
      env.value = !env.halted && (!block_given? || yield)
      next_sequence.invoke_after(env)
      env.value
    else
      invoke_sequence = Proc.new do
        skipped = nil
        while true
          current = next_sequence
          current.invoke_before(env)
          if current.final?
            env.value = !env.halted && (!block_given? || yield)
          elsif current.skip?(env)
            (skipped ||= []) << current
            next_sequence = next_sequence.nested
            next
          else
            next_sequence = next_sequence.nested
            begin
              target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
              target.send(method, *arguments, &block)
            ensure
              next_sequence = current
            end
          end
          current.invoke_after(env)
          skipped.pop.invoke_after(env) while skipped&.first
          break env.value
        end
      end
      invoke_sequence.call
    end
  end
end