/*
* call-seq:
* mtch[i] => str or nil
* mtch[start, length] => array
* mtch[range] => array
* mtch[name] => str or nil
*
* Match Reference---<code>MatchData</code> acts as an array, and may be
* accessed using the normal array indexing techniques. <i>mtch</i>[0] is
* equivalent to the special variable <code>$&</code>, and returns the entire
* matched string. <i>mtch</i>[1], <i>mtch</i>[2], and so on return the values
* of the matched backreferences (portions of the pattern between parentheses).
*
* m = /(.)(.)(\d+)(\d)/.match("THX1138.")
* m #=> #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
* m[0] #=> "HX1138"
* m[1, 2] #=> ["H", "X"]
* m[1..3] #=> ["H", "X", "113"]
* m[-3, 2] #=> ["X", "113"]
*
* m = /(?<foo>a+)b/.match("ccaaab")
* m #=> #<MatchData "aaab" foo:"aaa">
* m["foo"] #=> "aaa"
* m[:foo] #=> "aaa"
*/
static VALUE
match_aref(int argc, VALUE *argv, VALUE match)
{
VALUE idx, rest;
rb_scan_args(argc, argv, "11", &idx, &rest);
if (NIL_P(rest)) {
if (FIXNUM_P(idx)) {
if (FIX2INT(idx) >= 0) {
return rb_reg_nth_match(FIX2INT(idx), match);
}
}
else {
const char *p;
int num;
switch (TYPE(idx)) {
case T_SYMBOL:
p = rb_id2name(SYM2ID(idx));
goto name_to_backref;
break;
case T_STRING:
p = StringValuePtr(idx);
name_to_backref:
num = name_to_backref_number(RMATCH_REGS(match),
RMATCH(match)->regexp, p, p + strlen(p));
return rb_reg_nth_match(num, match);
break;
default:
break;
}
}
}
return rb_ary_aref(argc, argv, match_to_a(match));
}