[Bug #20936] Fix #size for Range#reverse_each
This commit is contained in:
parent
d5abcae435
commit
3422bfcab6
Notes:
git
2024-12-10 14:12:45 +00:00
51
range.c
51
range.c
@ -908,6 +908,10 @@ sym_each_i(VALUE v, VALUE arg)
|
|||||||
return each_i(rb_str_intern(v), arg);
|
return each_i(rb_str_intern(v), arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CANT_ITERATE_FROM(x) \
|
||||||
|
rb_raise(rb_eTypeError, "can't iterate from %s", \
|
||||||
|
rb_obj_classname(x))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* size -> non_negative_integer or Infinity or nil
|
* size -> non_negative_integer or Infinity or nil
|
||||||
@ -944,13 +948,48 @@ range_size(VALUE range)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!discrete_object_p(b)) {
|
if (!discrete_object_p(b)) {
|
||||||
rb_raise(rb_eTypeError, "can't iterate from %s",
|
CANT_ITERATE_FROM(b);
|
||||||
rb_obj_classname(b));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
range_reverse_size(VALUE range)
|
||||||
|
{
|
||||||
|
VALUE b = RANGE_BEG(range), e = RANGE_END(range);
|
||||||
|
|
||||||
|
if (NIL_P(e)) {
|
||||||
|
CANT_ITERATE_FROM(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RB_INTEGER_TYPE_P(b)) {
|
||||||
|
if (rb_obj_is_kind_of(e, rb_cNumeric)) {
|
||||||
|
return ruby_num_interval_step_size(b, e, INT2FIX(1), EXCL(range));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CANT_ITERATE_FROM(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NIL_P(b)) {
|
||||||
|
if (RB_INTEGER_TYPE_P(e)) {
|
||||||
|
return DBL2NUM(HUGE_VAL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CANT_ITERATE_FROM(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!discrete_object_p(b)) {
|
||||||
|
CANT_ITERATE_FROM(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CANT_ITERATE_FROM
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* to_a -> array
|
* to_a -> array
|
||||||
@ -979,6 +1018,12 @@ range_enum_size(VALUE range, VALUE args, VALUE eobj)
|
|||||||
return range_size(range);
|
return range_size(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
range_enum_reverse_size(VALUE range, VALUE args, VALUE eobj)
|
||||||
|
{
|
||||||
|
return range_reverse_size(range);
|
||||||
|
}
|
||||||
|
|
||||||
RBIMPL_ATTR_NORETURN()
|
RBIMPL_ATTR_NORETURN()
|
||||||
static void
|
static void
|
||||||
range_each_bignum_endless(VALUE beg)
|
range_each_bignum_endless(VALUE beg)
|
||||||
@ -1225,7 +1270,7 @@ range_reverse_each_negative_bignum_section(VALUE beg, VALUE end)
|
|||||||
static VALUE
|
static VALUE
|
||||||
range_reverse_each(VALUE range)
|
range_reverse_each(VALUE range)
|
||||||
{
|
{
|
||||||
RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_size);
|
RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_reverse_size);
|
||||||
|
|
||||||
VALUE beg = RANGE_BEG(range);
|
VALUE beg = RANGE_BEG(range);
|
||||||
VALUE end = RANGE_END(range);
|
VALUE end = RANGE_END(range);
|
||||||
|
@ -823,6 +823,25 @@ class TestRange < Test::Unit::TestCase
|
|||||||
assert_equal [5, 4, 3, 2, 1], a
|
assert_equal [5, 4, 3, 2, 1], a
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_reverse_each_size
|
||||||
|
assert_equal(3, (1..3).reverse_each.size)
|
||||||
|
assert_equal(3, (1..3.3).reverse_each.size)
|
||||||
|
assert_raise(TypeError) { (1..nil).reverse_each.size }
|
||||||
|
assert_raise(TypeError) { (1.1..3).reverse_each.size }
|
||||||
|
assert_raise(TypeError) { (1.1..3.3).reverse_each.size }
|
||||||
|
assert_raise(TypeError) { (1.1..nil).reverse_each.size }
|
||||||
|
assert_equal(Float::INFINITY, (..3).reverse_each.size)
|
||||||
|
assert_raise(TypeError) { (nil..3.3).reverse_each.size }
|
||||||
|
assert_raise(TypeError) { (nil..nil).reverse_each.size }
|
||||||
|
|
||||||
|
assert_equal(2, (1...3).reverse_each.size)
|
||||||
|
assert_equal(3, (1...3.3).reverse_each.size)
|
||||||
|
|
||||||
|
assert_equal(nil, ('a'..'z').reverse_each.size)
|
||||||
|
assert_raise(TypeError) { ('a'..).reverse_each.size }
|
||||||
|
assert_raise(TypeError) { (..'z').reverse_each.size }
|
||||||
|
end
|
||||||
|
|
||||||
def test_begin_end
|
def test_begin_end
|
||||||
assert_equal(0, (0..1).begin)
|
assert_equal(0, (0..1).begin)
|
||||||
assert_equal(1, (0..1).end)
|
assert_equal(1, (0..1).end)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user