From: "mame (Yusuke Endoh) via ruby-core" Date: 2025-10-29T01:52:56+00:00 Subject: [ruby-core:123580] [Ruby Bug#21513] Converting endless range to set hangs Issue #21513 has been updated by mame (Yusuke Endoh). Status changed from Closed to Open Assignee set to knu (Akinori MUSHA) The fix introduced another inconsistency: ``` $ ruby -e 'Enumerator.new(Float::INFINITY) {|g| loop { g << 1 } }.to_set' -e:1:in 'Enumerable#to_set': cannot initialize Set from an object with infinite size (ArgumentError) from -e:1:in '
' $ ruby -e 'Enumerator.new(Float::INFINITY) {|g| loop { g << 1 } }.to_a # hungs' ``` I think checking if `Range#end` is nil is good enough, instead of calling `#size`. Note that calling `#size` caused another practical issue #21654. @knu What do you think? ---------------------------------------- Bug #21513: Converting endless range to set hangs https://bugs.ruby-lang.org/issues/21513#change-114962 * Author: viralpraxis (Iaroslav Kurbatov) * Status: Open * Assignee: knu (Akinori MUSHA) * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Converting endless range to array raises: ``` shell ruby -e '(1..).to_a' -e:1:in 'Range#to_a': cannot convert endless range to an array (RangeError) from -e:1:in '
' ``` but converting to set does not: ``` shell 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 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. ``` shell ./ruby -v ruby 3.5.0dev (2025-07-14T20:34:32Z master a6d483971a) +PRISM [x86_64-linux] ``` -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/