Changed the behavior of mrb_range_beg_len(); close #3411

The new API is:

int mrb_range_beg_len(mrb, range, &beg, &len, len, trunc)

The new argument `trunc` is a boolean value that specifies
whether the function truncates the range. The new return value
is an integer instead of a boolean, that is:

 0: not a range
 1: range with proper edges
 2: out of range

To get the old behavior, you have to rewrite:

  mrb_range_beg_len(mrb, range, &beg, &len, len)

to:

  mrn_range_beg_len(mrb, range, &beg, &len, len, TRUE) == 1

[Breaking Change]
This commit is contained in:
Yukihiro "Matz" Matsumoto
2017-01-23 14:35:26 +09:00
parent 708088c5fa
commit 5e1d923381
6 changed files with 40 additions and 40 deletions
+9 -12
View File
@@ -742,7 +742,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self)
switch (mrb_type(index)) {
/* a[n..m] */
case MRB_TT_RANGE:
if (mrb_range_beg_len(mrb, index, &i, &len, a->len)) {
if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {
return ary_subseq(mrb, a, i, len);
}
else {
@@ -808,20 +808,17 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self)
mrb_ary_modify(mrb, mrb_ary_ptr(self));
if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) {
switch (mrb_type(v1)) {
/* a[n..m] = v */
case MRB_TT_RANGE:
if (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self))) {
mrb_ary_splice(mrb, self, i, len, v2);
}
break;
/* a[n] = v */
case MRB_TT_FIXNUM:
mrb_ary_set(mrb, self, mrb_fixnum(v1), v2);
break;
default:
switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) {
case 0: /* not range */
mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
break;
case 1: /* range */
mrb_ary_splice(mrb, self, i, len, v2);
break;
case 2: /* out of range */
mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1);
break;
}
return v2;
}