/*
 *  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));
}