mruby-regexp: accept Regexp argument in Regexp.new

Regexp.new(regexp) copies the source and flags from the given
Regexp object, matching CRuby behavior.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-03-21 14:33:49 +09:00
parent 893cb4edc4
commit 36a0f83db3
2 changed files with 26 additions and 3 deletions
+17 -2
View File
@@ -72,6 +72,7 @@ parse_flags(mrb_state *mrb, mrb_value flags_val)
/*
* Regexp.new(pattern, flags=nil)
* Regexp.new(regexp)
* Regexp.compile(pattern, flags=nil)
*/
static mrb_value
@@ -81,9 +82,23 @@ regexp_init(mrb_state *mrb, mrb_value self)
mrb_value flags_val = mrb_nil_value();
mrb_regexp_pattern *pat;
mrb_get_args(mrb, "S|o", &pattern, &flags_val);
mrb_get_args(mrb, "o|o", &pattern, &flags_val);
uint32_t flags;
/* If pattern is a Regexp, copy its source and flags */
if (mrb_obj_is_kind_of(mrb, pattern, mrb_class_get(mrb, "Regexp"))) {
mrb_value iflags = mrb_iv_get(mrb, pattern, mrb_intern_lit(mrb, "@flags"));
flags = mrb_nil_p(iflags) ? 0 : (uint32_t)mrb_integer(iflags);
pattern = mrb_iv_get(mrb, pattern, mrb_intern_lit(mrb, "@source"));
}
else {
if (!mrb_string_p(pattern)) {
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument type (expected String or Regexp)");
}
flags = parse_flags(mrb, flags_val);
}
uint32_t flags = parse_flags(mrb, flags_val);
pat = re_compile(mrb, RSTRING_PTR(pattern), RSTRING_LEN(pattern), flags);
DATA_TYPE(self) = &regexp_type;
+9 -1
View File
@@ -1,8 +1,16 @@
assert("Regexp.new") do
assert("Regexp.new with string") do
re = Regexp.new("abc")
assert_kind_of Regexp, re
end
assert("Regexp.new with regexp") do
r1 = Regexp.new("abc", Regexp::IGNORECASE)
r2 = Regexp.new(r1)
assert_equal r1.source, r2.source
assert_equal r1.options, r2.options
assert_true r2.match?("ABC")
end
assert("Regexp#match - simple") do
re = Regexp.new("abc")
md = re.match("xabcy")