Bug #21513
openConverting endless range to set hangs
Description
Converting endless range to array raises:
ruby -e '(1..).to_a'
-e:1:in 'Range#to_a': cannot convert endless range to an array (RangeError)
from -e:1:in '<main>'
but converting to set does not:
ruby -e '(1..).to_set # hangs'
I think it makes to raise in both cases for consistency. Something like this should do the trick:
diff --git i/prelude.rb w/prelude.rb
index f49cada637..11bfa3fc95 100644
--- i/prelude.rb
+++ w/prelude.rb
@@ -30,6 +30,10 @@ module Enumerable
# Makes a set from the enumerable object with given arguments.
# Passing arguments to this method is deprecated.
def to_set(*args, &block)
+ if self.class == Range && self.end.nil?
+ raise RangeError, "cannot convert endless range to a set"
+ end
+
klass = if args.empty?
Set
else
diff --git i/test/ruby/test_range.rb w/test/ruby/test_range.rb
index f875c0ab40..27b968641b 100644
--- i/test/ruby/test_range.rb
+++ w/test/ruby/test_range.rb
@@ -1541,4 +1541,11 @@ def test_overlap?
assert_not_operator((1...3), :overlap?, (3..4))
assert_not_operator((...3), :overlap?, (3..))
end
+
+ def test_to_set
+ assert_equal(Set[], (1..-1).to_set)
+ assert_equal(Set[1, 2, 3], (1..3).to_set)
+
+ assert_raise(RangeError) { (239..).to_set }
+ end
end
If this patch is accepted, I'll open a PR.
./ruby -v
ruby 3.5.0dev (2025-07-14T20:34:32Z master a6d483971a) +PRISM [x86_64-linux]
Updated by Dan0042 (Daniel DeLorme) 1 day ago
Raising an error should be the case for ANY endless range operations that result in an infinite loop and memory consumption. This is a very costly and hard to debug failure mode, and it happens for a large number of endless range methods.
Updated by nobu (Nobuyoshi Nakada) about 21 hours ago
Thank you, good catch.
I think that check should be in Range#to_set
, as well as Range#to_a
.
class Range
# Makes a set from the range with given arguments, if a finite
# collection; raises an exception otherwise.
# Passing arguments to this method is deprecated.
def to_set(...)
if self.end.nil?
raise RangeError, "cannot convert endless range to a set"
end
super
end
end
Updated by viralpraxis (Iaroslav Kurbatov) about 12 hours ago
I've opened https://github.com/ruby/ruby/pull/13902
Updated by nobu (Nobuyoshi Nakada) about 11 hours ago
I suspect this is a bug fix instead of a new feature, isn't it?
Updated by viralpraxis (Iaroslav Kurbatov) about 11 hours ago
- Tracker changed from Feature to Bug
- Backport set to 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
Updated by viralpraxis (Iaroslav Kurbatov) about 11 hours ago
- Subject changed from Raise on converting endless range to set to Converting endless range to set hangs
Updated by Dan0042 (Daniel DeLorme) about 11 hours ago
What's your opinion on adding the same raise/check for the following methods? They present the same infinite loop problem.
#count
#all?
#collect / #map
#collect_concat / #flat_map
#compact
#drop
#drop_while
#filter
#filter_map
#find_all / #select
#grep
#grep_v
#group_by
#inject / #reduce
#max_by / #min_by / #minmax_by
#none?
#one?
#partition
#sort / #sort_by
#sum
#tally
#to_h
#uniq