module ActiveSupport::Callbacks::ClassMethods

def define_callbacks(*names)

overwrite previous callbacks registered with #set_callback.
Calling +define_callbacks+ multiple times with the same +names+ will

!, ? or =.
+names+ passed to +define_callbacks+ must not end with

===== Notes

would call Audit#save.

define_callbacks :save, scope: [:name]

A declaration like

which callbacks are being defined.
callback (before/after/around) and +:name+ refers to the method on
and +:name+ have special meanings: +:kind+ refers to the kind of
case "kind" is "before" and "name" is "save". In this context +:kind+
by calling #{kind}_#{name} on the given instance. In this
would trigger Audit#before_save instead. That's constructed

define_callbacks :save, scope: [:kind, :name]

Audit#before will be called. On the other hand
In the above case whenever you save an account the method

end
end
end
puts 'save in main'
run_callbacks :save do
def save

set_callback :save, :before, Audit.new
define_callbacks :save

include ActiveSupport::Callbacks
class Account

end
end
puts 'Audit: before_save is called'
def before_save(caller)

end
puts 'Audit: before is called'
def before(caller)
class Audit

object is used as a callback.
* :scope - Indicates which methods should be executed when an

option is set to +nil+.
terminated or not. This option has no effect if :terminator
default after callbacks are executed no matter if callback chain was
callbacks should be terminated by the :terminator option. By
* :skip_after_callbacks_if_terminated - Determines if after

The default terminator halts the chain when a callback throws +:abort+.

any successive before and around callback is not executed.
In this example, if any before validate callbacks returns +false+,

define_callbacks :validate, terminator: ->(target, result_lambda) { result_lambda.call == false }

to the terminator lambda.
The current object and the result lambda of the callback will be provided
This should be a lambda to be executed.
being called and the event from being triggered.
callback chain, preventing following before and around callbacks from
* :terminator - Determines when a before filter will halt the

===== Options

define_callbacks :initialize, :save, :destroy
define_callbacks :validate

Define sets of events in the object life cycle that support callbacks.
def define_callbacks(*names)
  options = names.extract_options!
  names.each do |name|
    name = name.to_sym
    ([self] + self.descendants).each do |target|
      target.set_callbacks name, CallbackChain.new(name, options)
    end
    module_eval <<-RUBY, __FILE__, __LINE__ + 1
      def _run_#{name}_callbacks(&block)
        run_callbacks #{name.inspect}, &block
      end
      def self._#{name}_callbacks
        get_callbacks(#{name.inspect})
      end
      def self._#{name}_callbacks=(value)
        set_callbacks(#{name.inspect}, value)
      end
      def _#{name}_callbacks
        __callbacks[#{name.inspect}]
      end
    RUBY
  end
end