Bug #18635
closedEnumerable#inject without block/symbol will return values or raise LocalJumpError
Description
The following shows inconsistent behavior when no block/symbol are provided to inject.
irb(main):002:0> {}.inject
=> nil
irb(main):003:0> {one: 1}.inject
=> [:one, 1]
irb(main):004:0> {one: 1, two: 2}.inject
(irb):4:in `each': no block given (LocalJumpError)
irb(main):005:0> [].inject
=> nil
irb(main):006:0> [1].inject
=> 1
irb(main):007:0> [1, 2].inject
(irb):7:in `each': no block given (LocalJumpError)
I would expect the results to be consistent by always raising a LocalJumpError or raising an ArgumentError when no block and symbol are given.
Updated by jeremyevans0 (Jeremy Evans) almost 3 years ago
The call-seq for inject does not show usage without an argument or block, so I think it is reasonable to consider this as a bug, and it seems more likely to be a code bug than a doc bug. It's problematic that no error is raised when called on an enumerable with one or two elements, since that is likely to lead to cases that do not raise errors during testing, but raise errors in real world environments.
LocalJumpError is raised when there is an attempt to yield to a block, but no block was passed. Enumerable#inject
with zero or 1 arguments does not attempt to yield to a block, so it doesn't make sense to raise LocalJumpError. I think ArgumentError if passed no arguments and no block is a better fit. I submitted a pull request for that: https://github.com/ruby/ruby/pull/5690
Updated by Eregon (Benoit Daloze) almost 3 years ago
I think either is fine.
I think some methods raise LocalJumpError early, even if they didn't try to use the block yet, so LocalJumpError would also be reasonable.
My view is the general form of #inspect is the block version, and the Symbol is just a shorthand for the block.
So in that view LocalJumpError is a bit better.
But either way, no code should do this so any of these exceptions is helpful.
Updated by jeremyevans (Jeremy Evans) almost 3 years ago
- Status changed from Open to Closed
Applied in changeset git|8f1c69f27ce6b3f5ed1c1cf8d2aa62aa9701d636.
Raise ArgumentError when calling Enumberable#inject without block or arguments
Previously, this would work as expected if the enumerable contained
0 or 1 element, and would raise LocalJumpError otherwise. That
inconsistent behavior is likely to lead to bugs.
Fixes [Bug #18635]