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) 5 days 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) 4 days 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) 4 days ago
I've opened https://github.com/ruby/ruby/pull/13902
Updated by nobu (Nobuyoshi Nakada) 4 days ago
I suspect this is a bug fix instead of a new feature, isn't it?
Updated by viralpraxis (Iaroslav Kurbatov) 4 days ago
- Tracker changed from Feature to Bug
- Backport set to 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
Updated by viralpraxis (Iaroslav Kurbatov) 4 days ago
- Subject changed from Raise on converting endless range to set to Converting endless range to set hangs
Updated by Dan0042 (Daniel DeLorme) 4 days 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