From b09f5c7bf79d347aa6ed92964cff16d7da008ad9 Mon Sep 17 00:00:00 2001 From: Vladimir Dementyev Date: Tue, 18 Apr 2023 19:19:31 -0400 Subject: MatchData#named_captures: add optional symbolize_names keyword (#6952) --- re.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 're.c') diff --git a/re.c b/re.c index c097c0f378..d7490bbbbf 100644 --- a/re.c +++ b/re.c @@ -2316,7 +2316,7 @@ match_named_captures_iter(const OnigUChar *name, const OnigUChar *name_end, /* * call-seq: - * named_captures -> hash + * named_captures(symbolize_names: false) -> hash * * Returns a hash of the named captures; * each key is a capture name; each value is its captured string or +nil+: @@ -2337,10 +2337,17 @@ match_named_captures_iter(const OnigUChar *name, const OnigUChar *name_end, * # => # * m.named_captures #=> {"a" => "1"} * + * If keyword argument +symbolize_names+ is given + * a true value, the keys in the resulting hash are Symbols: + * + * m = /(?.)(?.)/.match("01") + * # => # + * m.named_captures(symbolize_names: true) #=> {:a => "1"} + * */ static VALUE -match_named_captures(VALUE match) +match_named_captures(int argc, VALUE *argv, VALUE match) { VALUE hash; struct MEMO *memo; @@ -2349,8 +2356,27 @@ match_named_captures(VALUE match) if (NIL_P(RMATCH(match)->regexp)) return rb_hash_new(); + VALUE opt; + VALUE symbolize_names = 0; + + rb_scan_args(argc, argv, "0:", &opt); + + if (!NIL_P(opt)) { + static ID keyword_ids[1]; + + VALUE symbolize_names_val; + + if (!keyword_ids[0]) { + keyword_ids[0] = rb_intern_const("symbolize_names"); + } + rb_get_kwargs(opt, keyword_ids, 0, 1, &symbolize_names_val); + if (!UNDEF_P(symbolize_names_val) && RTEST(symbolize_names_val)) { + symbolize_names = 1; + } + } + hash = rb_hash_new(); - memo = MEMO_NEW(hash, match, 0); + memo = MEMO_NEW(hash, match, symbolize_names); onig_foreach_name(RREGEXP(RMATCH(match)->regexp)->ptr, match_named_captures_iter, (void*)memo); @@ -4754,7 +4780,7 @@ Init_Regexp(void) rb_define_method(rb_cMatch, "[]", match_aref, -1); rb_define_method(rb_cMatch, "captures", match_captures, 0); rb_define_alias(rb_cMatch, "deconstruct", "captures"); - rb_define_method(rb_cMatch, "named_captures", match_named_captures, 0); + rb_define_method(rb_cMatch, "named_captures", match_named_captures, -1); rb_define_method(rb_cMatch, "deconstruct_keys", match_deconstruct_keys, 1); rb_define_method(rb_cMatch, "values_at", match_values_at, -1); rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0); -- cgit v1.2.1