module ActiveSupport::Callbacks

def halted_callback_hook(filter)

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)
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
    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 && skipped.first
        break env.value
      end
    end
    # 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.call
    end
  end
end