static mrb_value mrb_ary_aget(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); mrb_int i, len; mrb_value index; if (mrb_get_args(mrb, "o|i", &index, &len) == 1) { switch (mrb_type(index)) { /* a[n..m] */ case MRB_TT_RANGE: if (mrb_range_beg_len(mrb, index, &i, &len, a->len)) { return ary_subseq(mrb, a, i, len); } else { return mrb_nil_value(); } case MRB_TT_FIXNUM: return mrb_ary_ref(mrb, self, mrb_fixnum(index)); default: return mrb_ary_ref(mrb, self, aget_index(mrb, index)); } } i = aget_index(mrb, index); if (i < 0) i += a->len; if (i < 0 || a->len < i) return mrb_nil_value(); if (len < 0) return mrb_nil_value(); if (a->len == i) return mrb_ary_new(mrb); if (len > a->len - i) len = a->len - i; return ary_subseq(mrb, a, i, len); }
static mrb_value mrb_ary_aset(mrb_state *mrb, mrb_value self) { mrb_value v1, v2, v3; mrb_int i, len; 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: mrb_ary_set(mrb, self, aget_index(mrb, v1), v2); break; } return v2; } /* a[n,m] = v */ mrb_ary_splice(mrb, self, aget_index(mrb, v1), aget_index(mrb, v2), v3); return v3; }
static mrb_value mrb_ary_aset(mrb_state *mrb, mrb_value self) { mrb_value v1, v2, v3; mrb_int i, len; mrb_ary_modify(mrb, mrb_ary_ptr(self)); if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) { /* a[n..m] = v */ 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; } /* a[n,m] = v */ mrb_ary_splice(mrb, self, aget_index(mrb, v1), aget_index(mrb, v2), v3); return v3; }