Actions
Bug #21525
closedInconsistent execution order for methods with constant blocks
Bug #21525:
Inconsistent execution order for methods with constant blocks
Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.4.5 (2025-08-01 revision 07f7832cff) +PRISM [arm64-darwin24]
Description
If you call a method and pass in a splat of an array with a block argument coerced from calling a method, Ruby maintains the expected execution order and the called method receives a copy of the array prior to modification.
In this example, the output is [1, 2, 3] since the copy is made before the bar method can modify it.
ARRAY = [1, 2, 3]
def bar
ARRAY.pop
-> {}
end
def example(*args, &)
puts args
end
example(*ARRAY, &bar)
However, when passing a constant, the block coercion itself is able to modify the array.
ARRAY = [1, 2, 3]
module Foo
module Bar
def self.to_proc
ARRAY.pop
-> {}
end
end
end
def example(*args, &)
puts args
end
example(*ARRAY, &Foo::Bar)
Another way to trigger this is to define a const_missing method that modifies the array.
ARRAY = [1, 2, 3]
module Foo
def self.const_missing(name)
ARRAY.pop
-> {}
end
end
def example(*args, &)
puts args
end
example(*ARRAY, &Foo::Bar)
In both these cases, the output is [1, 2] instead of the expected [1, 2, 3].
Actions