Project

General

Profile

Actions

Feature #18551

closed

Make `Range#reverse_each` to raise an exception if endless

Added by kyanagi (Kouhei Yanagita) about 2 years ago. Updated 5 months ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:107299]

Description

https://github.com/ruby/ruby/pull/5498

Currently, Range#reverse_each for an endless range never returns.

% ruby -e '(1..).reverse_each { }'
# never return ...

(This is because Enumerable#reverse_each tries #to_a and #to_a for an endless range comes into an infinite loop.)

I think Range#reverse_each for an endless range should raise an exception, similar to Range#each for a beginless range.

% ruby -e '(..1).each { }' 
-e:1:in `each': can't iterate from NilClass (TypeError)
	from -e:1:in `<main>'

Updated by Eregon (Benoit Daloze) about 2 years ago

There is no Range#reverse_each currently, only Enumerable#reverse_each, and Enumerable can't know about this.
But maybe it makes sense to have Range#reverse_each for this and maybe also for faster reverse_each on Numeric Ranges?
OTOH Range operations that work differently for numerics tend to make Range even more messy when it comes to non-numeric values (more differences in behavior, can't reverse_each efficiently on Date/Time/etc).

Updated by Eregon (Benoit Daloze) about 2 years ago

I checked the PR, seems a useful change to me.

Updated by Dan0042 (Daniel DeLorme) about 2 years ago

Yes, this is a useful change. Although wouldn't it be better to prevent #to_a instead of only #reverse_each ?

Actually there's quite a lot of Enumerable methods that would be better raising an exception for endless ranges.
For example: (1..).select{ true } results in infinite loop and memory consumption.
The only way out is break, but then there's no point using select since it can't return a result.
The same applies to reject, partition, sort, zip, uniq, tally, etc...

Updated by kyanagi (Kouhei Yanagita) about 2 years ago

Eregon (Benoit Daloze) wrote in #note-1:

OTOH Range operations that work differently for numerics tend to make Range even more messy when it comes to non-numeric values (more differences in behavior, can't reverse_each efficiently on Date/Time/etc).

I posted another ticket for performance issue: #18515
I wrote my thoughts there.

Actions #5

Updated by nobu (Nobuyoshi Nakada) 5 months ago

  • Subject changed from Make Range#reverse_each to raise an exception if endless to Make `Range#reverse_each` to raise an exception if endless

Updated by mame (Yusuke Endoh) 5 months ago

In the previous dev meething, matz accepted this. I will merge the PR

Actions #7

Updated by kyanagi (Kouhei Yanagita) 5 months ago

  • Status changed from Open to Closed

Applied in changeset git|458d079166ce7344c1d44b2403ff963b8c68d7d8.


[DOC] Add a mention of [Feature #18551] to NEWS.md

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0