[前][次][番号順一覧][スレッド一覧]

ruby-changes:72256

From: Nobuyoshi <ko1@a...>
Date: Mon, 20 Jun 2022 19:35:32 +0900 (JST)
Subject: [ruby-changes:72256] 1e9939dae2 (master): [Feature #18788] Support options as `String` to `Regexp.new`

https://git.ruby-lang.org/ruby.git/commit/?id=1e9939dae2

From 1e9939dae24db232d6f3693630fa37a382e1a6d7 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Thu, 16 Jun 2022 18:53:35 +0900
Subject: [Feature #18788] Support options as `String` to `Regexp.new`

`Regexp.new` now supports passing the regexp flags not only as an
`Integer`, but also as a `String.  Unknown flags raise errors.
---
 NEWS.md                  |  6 ++++--
 re.c                     | 21 +++++++++++++++++++++
 test/ruby/test_regexp.rb | 17 +++++++++++++++++
 3 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/NEWS.md b/NEWS.md
index 02163ff9c0..129cd45a1c 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -119,8 +119,10 @@ Note: We're only listing outstanding class updates. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L119
     * Proc#parameters now accepts lambda keyword. [[Feature #15357]]
 
 * Regexp
-    * Regexp.new now warns second argument, other than `true`, `false`,
-      `nil` or Integer.  [[Feature #18788]]
+    * Regexp.new now supports passing the regexp flags not only as an Integer,
+      but also as a String Unknown flags raise errors.  Otherwise, anything
+      other than `true`, `false`, `nil` or Integer will be warned.
+      [[Feature #18788]]
 
 * Refinement
     * Refinement#refined_class has been added. [[Feature #12737]]
diff --git a/re.c b/re.c
index f225a413d5..39d4fc046f 100644
--- a/re.c
+++ b/re.c
@@ -3632,6 +3632,25 @@ rb_reg_match_p(VALUE re, VALUE str, long pos) https://github.com/ruby/ruby/blob/trunk/re.c#L3632
  * Alias for Regexp.new
  */
 
+static int
+str_to_option(VALUE str)
+{
+    int flag = 0;
+    const char *ptr;
+    long len;
+    str = rb_check_string_type(str);
+    if (NIL_P(str)) return -1;
+    RSTRING_GETMEM(str, ptr, len);
+    for (long i = 0; i < len; ++i) {
+	int f = char_to_option(ptr[i]);
+	if (!f) {
+	    rb_raise(rb_eArgError, "unknown regexp option: %"PRIsVALUE, str);
+	}
+	flag |= f;
+    }
+    return flag;
+}
+
 /*
  *  call-seq:
  *    Regexp.new(string, options = 0, n_flag = nil, timeout: nil) -> regexp
@@ -3716,7 +3735,9 @@ rb_reg_initialize_m(int argc, VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/re.c#L3735
     }
     else {
         if (opts != Qundef) {
+	    int f;
 	    if (FIXNUM_P(opts)) flags = FIX2INT(opts);
+	    else if ((f = str_to_option(opts)) >= 0) flags = f;
 	    else if (!NIL_P(opts) && rb_bool_expected(opts, "ignorecase", FALSE))
 		flags = ONIG_OPTION_IGNORECASE;
 	}
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index 5ee6b1b03c..1d93d1a5b1 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -634,6 +634,23 @@ class TestRegexp < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_regexp.rb#L634
     end
   end
 
+  def test_initialize_option
+    assert_equal(//i, Regexp.new("", "i"))
+    assert_equal(//m, Regexp.new("", "m"))
+    assert_equal(//x, Regexp.new("", "x"))
+    assert_equal(//imx, Regexp.new("", "imx"))
+    assert_equal(//, Regexp.new("", ""))
+    assert_equal(//imx, Regexp.new("", "mimix"))
+
+    assert_raise(ArgumentError) { Regexp.new("", "e") }
+    assert_raise(ArgumentError) { Regexp.new("", "n") }
+    assert_raise(ArgumentError) { Regexp.new("", "s") }
+    assert_raise(ArgumentError) { Regexp.new("", "u") }
+    assert_raise(ArgumentError) { Regexp.new("", "o") }
+    assert_raise(ArgumentError) { Regexp.new("", "j") }
+    assert_raise(ArgumentError) { Regexp.new("", "xmen") }
+  end
+
   def test_match_control_meta_escape
     assert_equal(0, /\c\xFF/ =~ "\c\xFF")
     assert_equal(0, /\c\M-\xFF/ =~ "\c\M-\xFF")
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]