Permalink
Browse files

Allow access to a callback event's return result from around callbacks

  • Loading branch information...
1 parent 1408b94 commit df615f127ece4f712448ae5bd3e993ec378d8f7a @obrie obrie committed with josevalim Mar 7, 2011
Showing with 32 additions and 2 deletions.
  1. +8 −2 activesupport/lib/active_support/callbacks.rb
  2. +24 −0 activesupport/test/callbacks_test.rb
View
10 activesupport/lib/active_support/callbacks.rb
@@ -225,7 +225,10 @@ def end(key=nil, object=nil)
# end
[@compiled_options[0], @filter, @compiled_options[1]].compact.join("\n")
when :around
- "end"
+ <<-RUBY_EVAL
+ value
+ end
+ RUBY_EVAL
end
end
@@ -423,7 +426,7 @@ def __update_callbacks(name, filters = [], block = nil) #:nodoc:
#
# set_callback :save, :before, :before_meth
# set_callback :save, :after, :after_meth, :if => :condition
- # set_callback :save, :around, lambda { |r| stuff; yield; stuff }
+ # set_callback :save, :around, lambda { |r| stuff; result = yield; stuff }
#
# The second arguments indicates whether the callback is to be run +:before+,
# +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This
@@ -442,6 +445,9 @@ def __update_callbacks(name, filters = [], block = nil) #:nodoc:
#
# Before and around callbacks are called in the order that they are set; after
# callbacks are called in the reverse order.
+ #
+ # Around callbacks can access the return value from the event, if it
+ # wasn't halted, from the +yield+ call.
#
# ===== Options
#
View
24 activesupport/test/callbacks_test.rb
@@ -299,6 +299,22 @@ def save
end
end
end
+
+ class AroundPersonResult < MySuper
+ attr_reader :result
+
+ set_callback :save, :around, :tweedle_dum
+
+ def tweedle_dum
+ @result = yield
+ end
+
+ def save
+ run_callbacks :save do
+ :running
+ end
+ end
+ end
class HyphenatedCallbacks
include ActiveSupport::Callbacks
@@ -338,6 +354,14 @@ def test_save_around
], around.history
end
end
+
+ class AroundCallbackResultTest < Test::Unit::TestCase
+ def test_save_around
+ around = AroundPersonResult.new
+ around.save
+ assert_equal :running, around.result
+ end
+ end
class SkipCallbacksTest < Test::Unit::TestCase
def test_skip_person

0 comments on commit df615f1

Please sign in to comment.