aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/callbacks.rb
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2016-12-15 19:23:10 +1030
committerMatthew Draper <matthew@trebex.net>2016-12-15 19:23:10 +1030
commit833ea903a9591b3b7d805981c0d0dbadf53cb58d (patch)
treef3e32b052bb530414007583141a52256e2795317 /activesupport/lib/active_support/callbacks.rb
parentcfc126e150659f91ccc0892197e7825af7c7327b (diff)
downloadrails-833ea903a9591b3b7d805981c0d0dbadf53cb58d.tar.gz
rails-833ea903a9591b3b7d805981c0d0dbadf53cb58d.tar.bz2
rails-833ea903a9591b3b7d805981c0d0dbadf53cb58d.zip
Support double-yield inside an around callback
It's questionable whether this is a good thing -- it forces any later/ inner callback to handle multiple invocations, along with the actual wrapped action. But it worked prior to 871ca21f6a1d65c0ec78cb5a9641411e2210460b, so we shouldn't break it unintentionally.
Diffstat (limited to 'activesupport/lib/active_support/callbacks.rb')
-rw-r--r--activesupport/lib/active_support/callbacks.rb12
1 files changed, 9 insertions, 3 deletions
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index af8ddb176f..e6c79f2a38 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -109,16 +109,22 @@ module ActiveSupport
invoke_sequence = Proc.new do
skipped = nil
while true
- current, next_sequence = next_sequence, next_sequence.nested
+ 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
- target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
- target.send(method, *arguments, &block)
+ 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