модуль ActiveSupport::Callbacks
Callbacks — это крючки кода, которые выполняются в ключевые моменты жизненного цикла объекта. Типичный случай использования — определение набора обратных вызовов в базовом классе, относящихся к другим функциям, которые он предоставляет, таким образом, подклассы могут устанавливать обратные вызовы, которые улучшают или изменяют базовые функции, без необходимости переопределять методы базового класса.
Включение этого модуля позволяет определять события в жизненном цикле объекта, которые будут поддерживать обратные вызовы (через ClassMethods.define_callbacks), устанавливать методы экземпляра, проги или объекты обратного вызова, которые будут вызываться (через ClassMethods.set_callback), и запускать установленные обратные вызовы в соответствующие моменты времени (через run_callbacks).
По умолчанию обратные вызовы останавливаются, выбрасывая :abort. Подробности см. в ClassMethods.define_callbacks.
Поддерживаются три вида обратных вызовов: обратные вызовы до, выполняемые перед определенным событием; обратные вызовы после, выполняемые после события; и обратные вызовы вокруг, блоки, окружающие событие, вызывающие его, когда они передают управление.
Код обратного вызова может содержаться в методах экземпляра, прогах или лямбда-функциях, или в объектах обратного вызова, которые отвечают на определенные предварительно определенные методы. Подробности см. в ClassMethods.set_callback.
class Record
include ActiveSupport::Callbacks
define_callbacks :save
def save
run_callbacks :save do
puts "- save"
end
end
end
class PersonRecord < Record
set_callback :save, :before, :saving_message
def saving_message
puts "saving..."
end
set_callback :save, :after do |object|
puts "saved"
end
end
person = PersonRecord.new
person.save
Вывод:
saving... - save saved
Константы
- CALLBACK_FILTER_TYPES
Открытые методы экземпляров
# File activesupport/lib/active_support/callbacks.rb, line 95
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 Выполняет обратные вызовы для данного события.
Вызывает обратные вызовы до и вокруг в порядке их установки, передает управление блоком (если он задан), а затем выполняет обратные вызовы после в обратном порядке.
Если цепочка обратных вызовов была остановлена, возвращает false. В противном случае возвращает результат блока, nil если обратные вызовы не были установлены, или true если обратные вызовы были установлены, но блок не задан.
run_callbacks :save do save end
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.