summaryrefslogtreecommitdiff
path: root/re.c
diff options
context:
space:
mode:
authorVladimir Dementyev <dementiev.vm@gmail.com>2023-04-18 19:19:31 -0400
committerGitHub <noreply@github.com>2023-04-19 11:19:31 +1200
commitb09f5c7bf79d347aa6ed92964cff16d7da008ad9 (patch)
tree7166e834c07ed543bd9c1b86578748b718fddcf8 /re.c
parent2dff1d4fdabd0fafeeac675baaaf7b06bb3150f9 (diff)
downloadruby-b09f5c7bf79d347aa6ed92964cff16d7da008ad9.tar.gz
MatchData#named_captures: add optional symbolize_names keyword (#6952)
Diffstat (limited to 're.c')
-rw-r--r--re.c34
1 files changed, 30 insertions, 4 deletions
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,
* # => #<MatchData "01" a:"0" a:"1">
* m.named_captures #=> {"a" => "1"}
*
+ * If keyword argument +symbolize_names+ is given
+ * a true value, the keys in the resulting hash are Symbols:
+ *
+ * m = /(?<a>.)(?<a>.)/.match("01")
+ * # => #<MatchData "01" a:"0" a:"1">
+ * 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);