Actions
Bug #21525
closedInconsistent 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
Like0
Like1Like0Like0Like0