Skip to content

Commit a5a7db6

Browse files
committed
[Feature #21513] Raise on converting endless range to set
Before this patch, trying to convert endless range (e.g. `(1..)`) to set (using `to_set`) would hang
1 parent 5723945 commit a5a7db6

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

range.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,31 @@ range_to_a(VALUE range)
10171017
return rb_call_super(0, 0);
10181018
}
10191019

1020+
/*
1021+
* call-seq:
1022+
* to_set -> set
1023+
*
1024+
* Returns a set containing the elements in +self+, if a finite collection;
1025+
* raises an exception otherwise.
1026+
*
1027+
* (1..4).to_set # => Set[1, 2, 3, 4]
1028+
* (1...4).to_set # => Set[1, 2, 3]
1029+
* ('a'..'d').to_set # => Set["a", "b", "c", "d"]
1030+
* (..'d').to_set # RangeError
1031+
* ('a'..).to_set # RangeError
1032+
*
1033+
*/
1034+
1035+
1036+
static VALUE
1037+
range_to_set(VALUE range)
1038+
{
1039+
if (NIL_P(RANGE_BEG(range)) || NIL_P(RANGE_END(range))) {
1040+
rb_raise(rb_eRangeError, "cannot convert infinite range to a set");
1041+
}
1042+
return rb_call_super(0, 0);
1043+
}
1044+
10201045
static VALUE
10211046
range_enum_size(VALUE range, VALUE args, VALUE eobj)
10221047
{
@@ -2847,6 +2872,7 @@ Init_Range(void)
28472872
rb_define_method(rb_cRange, "entries", range_to_a, 0);
28482873
rb_define_method(rb_cRange, "to_s", range_to_s, 0);
28492874
rb_define_method(rb_cRange, "inspect", range_inspect, 0);
2875+
rb_define_method(rb_cRange, "to_set", range_to_set, 0);
28502876

28512877
rb_define_method(rb_cRange, "exclude_end?", range_exclude_end_p, 0);
28522878

test/ruby/test_range.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,4 +1541,14 @@ def test_overlap?
15411541
assert_not_operator((1...3), :overlap?, (3..4))
15421542
assert_not_operator((...3), :overlap?, (3..))
15431543
end
1544+
1545+
def test_to_set
1546+
assert_equal(Set[], (1..-1).to_set)
1547+
assert_equal(Set[1, 2, 3], (1..3).to_set)
1548+
assert_equal(Set['a', 'b', 'c'], ('a'..'c').to_set)
1549+
1550+
assert_raise(RangeError) { (239..).to_set }
1551+
assert_raise(RangeError) { (...239).to_set }
1552+
assert_raise(RangeError) { (nil...nil).to_set }
1553+
end
15441554
end

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy