mruby-regexp: implement Regexp#to_s in CRuby-compatible format

Regexp#to_s now returns (?flags:source) format (e.g. "(?i:abc)")
instead of the /source/flags format used by Regexp#inspect.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-03-21 14:12:05 +09:00
parent 4d81275083
commit dab150007f
2 changed files with 25 additions and 2 deletions
+18 -2
View File
@@ -252,8 +252,24 @@ regexp_source(mrb_state *mrb, mrb_value self)
}
/*
* Regexp#inspect
* Regexp#to_s - CRuby-compatible (?flags:source) format
*/
static mrb_value
regexp_to_s(mrb_state *mrb, mrb_value self)
{
mrb_value src = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@source"));
mrb_value flags_val = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@flags"));
uint32_t flags = mrb_nil_p(flags_val) ? 0 : (uint32_t)mrb_integer(flags_val);
mrb_value result = mrb_str_new_lit(mrb, "(?");
if (flags & RE_FLAG_IGNORECASE) mrb_str_cat_lit(mrb, result, "i");
if (flags & RE_FLAG_MULTILINE) mrb_str_cat_lit(mrb, result, "m");
mrb_str_cat_lit(mrb, result, ":");
mrb_str_cat_str(mrb, result, src);
mrb_str_cat_lit(mrb, result, ")");
return result;
}
static mrb_value
regexp_inspect(mrb_state *mrb, mrb_value self)
{
@@ -515,7 +531,7 @@ mrb_mruby_regexp_gem_init(mrb_state *mrb)
mrb_define_method(mrb, re, "===", regexp_case_match, MRB_ARGS_REQ(1));
mrb_define_method(mrb, re, "source", regexp_source, MRB_ARGS_NONE());
mrb_define_method(mrb, re, "inspect", regexp_inspect, MRB_ARGS_NONE());
mrb_define_method(mrb, re, "to_s", regexp_inspect, MRB_ARGS_NONE());
mrb_define_method(mrb, re, "to_s", regexp_to_s, MRB_ARGS_NONE());
/* MatchData class */
struct RClass *md = mrb_define_class(mrb, "MatchData", mrb->object_class);
+7
View File
@@ -122,6 +122,13 @@ assert("Regexp#inspect") do
assert_equal "/abc/i", re.inspect
end
assert("Regexp#to_s") do
assert_equal "(?:abc)", Regexp.new("abc").to_s
assert_equal "(?i:abc)", Regexp.new("abc", Regexp::IGNORECASE).to_s
assert_equal "(?m:abc)", Regexp.new("abc", Regexp::MULTILINE).to_s
assert_equal "(?im:abc)", Regexp.new("abc", Regexp::IGNORECASE | Regexp::MULTILINE).to_s
end
assert("String#match") do
md = "hello world".match(Regexp.new("(\\w+)\\s(\\w+)"))
assert_equal "hello", md[1]