From 87378b0b6d5361d380ce85e4c08b147a9e7c375b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 11:48:04 -0700 Subject: polymorphic around callbacks --- activesupport/lib/active_support/callbacks.rb | 94 ++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 15 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 0ae69832bd..cc4f589203 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -245,6 +245,84 @@ module ActiveSupport } end end + + class Around + def self.build(next_callback, user_callback, user_conditions, chain_config) + if chain_config.key?(:terminator) && user_conditions.any? + halting_and_conditional(next_callback, user_callback, user_conditions) + elsif chain_config.key? :terminator + halting(next_callback, user_callback) + elsif user_conditions.any? + conditional(next_callback, user_callback, user_conditions) + else + simple(next_callback, user_callback) + end + end + + private + + def self.halting_and_conditional(next_callback, user_callback, user_conditions) + lambda { |env| + target = env.target + value = env.value + halted = env.halted + + if !halted && user_conditions.all? { |c| c.call(target, value) } + user_callback.call(target, value) { + env = next_callback.call env + env.value + } + env + else + next_callback.call env + end + } + end + + def self.halting(next_callback, user_callback) + lambda { |env| + target = env.target + value = env.value + + if !env.halted + user_callback.call(target, value) { + env = next_callback.call env + env.value + } + env + else + next_callback.call env + end + } + end + + def self.conditional(next_callback, user_callback, user_conditions) + lambda { |env| + target = env.target + value = env.value + + if user_conditions.all? { |c| c.call(target, value) } + user_callback.call(target, value) { + env = next_callback.call env + env.value + } + env + else + next_callback.call env + end + } + end + + def self.simple(next_callback, user_callback) + lambda { |env| + user_callback.call(env.target, env.value) { + env = next_callback.call env + env.value + } + env + } + end + end end class Callback #:nodoc:# @@ -319,21 +397,7 @@ module ActiveSupport when :after Filters::After.build(next_callback, user_callback, user_conditions, chain_config) when :around - lambda { |env| - target = env.target - value = env.value - halted = env.halted - - if !halted && user_conditions.all? { |c| c.call(target, value) } - user_callback.call(target, value) { - env = next_callback.call env - env.value - } - env - else - next_callback.call env - end - } + Filters::Around.build(next_callback, user_callback, user_conditions, chain_config) end end -- cgit v1.2.3