aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Oliver Nutter <headius@headius.com>2016-10-21 09:33:25 -0500
committerCharles Oliver Nutter <headius@headius.com>2016-10-21 09:33:25 -0500
commit5f382d41c30b1e433d777a8daaedb247d7f2a57c (patch)
treeb7914f0112dc21c60b6bdff8209b7f0c7e6f23e0
parentf2c6db41ba56afb1529e4732c59622fc0cf9f3ba (diff)
downloadrails-5f382d41c30b1e433d777a8daaedb247d7f2a57c.tar.gz
rails-5f382d41c30b1e433d777a8daaedb247d7f2a57c.tar.bz2
rails-5f382d41c30b1e433d777a8daaedb247d7f2a57c.zip
Explicitly unpack the expanded args to avoid execution order diff.
In https://bugs.ruby-lang.org/issues/12860 I argue that MRI's execution order here is incorrect. The splatting of the 'c' args should happen before the shift, but it happens after. On JRuby, it behaves the way you would expect, leading to the 'c' args splat still containing the block and producing an error like "cannot convert proc to symbol" when the send attempts to coerce it. This patch makes the unpacking order explicit with a multi-assign, which behaves properly on all implementations I tested.
-rw-r--r--activesupport/lib/active_support/callbacks.rb8
1 files changed, 4 insertions, 4 deletions
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 890b1cd73b..9b9c9cbbdd 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -410,8 +410,8 @@ module ActiveSupport
# values.
def make_lambda
lambda do |target, value, &block|
- c = expand(target, value, block)
- c.shift.send(*c, &c.shift)
+ target, block, method, *arguments = expand(target, value, block)
+ target.send(method, *arguments, &block)
end
end
@@ -419,8 +419,8 @@ module ActiveSupport
# values, but then return the boolean inverse of that result.
def inverted_lambda
lambda do |target, value, &block|
- c = expand(target, value, block)
- ! c.shift.send(*c, &c.shift)
+ target, block, method, *arguments = expand(target, value, block)
+ ! target.send(method, *arguments, &block)
end
end