mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
* Support ArithmeticSequence in Array#slice * Extract rb_range_component_beg_len * Use rb_range_values to check Range object * Fix ary_make_partial_step * Fix for negative step cases * range.c: Describe the role of err argument in rb_range_component_beg_len * Raise a RangeError when an arithmetic sequence refers the outside of an array [Feature #16812]
This commit is contained in:
parent
081cc4eb28
commit
a6a8576e87
Notes:
git
2020-10-21 02:40:53 +09:00
Merged-By: mrkn <mrkn@ruby-lang.org>
6 changed files with 216 additions and 31 deletions
44
enumerator.c
44
enumerator.c
|
@ -3410,17 +3410,53 @@ rb_arithmetic_sequence_extract(VALUE obj, rb_arithmetic_sequence_components_t *c
|
|||
component->exclude_end = arith_seq_exclude_end_p(obj);
|
||||
return 1;
|
||||
}
|
||||
else if (rb_obj_is_kind_of(obj, rb_cRange)) {
|
||||
component->begin = RANGE_BEG(obj);
|
||||
component->end = RANGE_END(obj);
|
||||
else if (rb_range_values(obj, &component->begin, &component->end, &component->exclude_end)) {
|
||||
component->step = INT2FIX(1);
|
||||
component->exclude_end = RTEST(RANGE_EXCL(obj));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_arithmetic_sequence_beg_len_step(VALUE obj, long *begp, long *lenp, long *stepp, long len, int err)
|
||||
{
|
||||
RUBY_ASSERT(begp != NULL);
|
||||
RUBY_ASSERT(lenp != NULL);
|
||||
RUBY_ASSERT(stepp != NULL);
|
||||
|
||||
rb_arithmetic_sequence_components_t aseq;
|
||||
if (!rb_arithmetic_sequence_extract(obj, &aseq)) {
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
long step = NIL_P(aseq.step) ? 1 : NUM2LONG(aseq.step);
|
||||
*stepp = step;
|
||||
|
||||
if (step < 0) {
|
||||
VALUE tmp = aseq.begin;
|
||||
aseq.begin = aseq.end;
|
||||
aseq.end = tmp;
|
||||
}
|
||||
|
||||
if (err == 0 && (step < -1 || step > 1)) {
|
||||
if (rb_range_component_beg_len(aseq.begin, aseq.end, aseq.exclude_end, begp, lenp, len, 1) == Qtrue) {
|
||||
if (*begp > len)
|
||||
goto out_of_range;
|
||||
if (*lenp > len)
|
||||
goto out_of_range;
|
||||
return Qtrue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return rb_range_component_beg_len(aseq.begin, aseq.end, aseq.exclude_end, begp, lenp, len, err);
|
||||
}
|
||||
|
||||
out_of_range:
|
||||
rb_raise(rb_eRangeError, "%+"PRIsVALUE" out of range", obj);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* aseq.first -> num or nil
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue