Project

General

Profile

Actions

Feature #19344

open

Regexp.new: stricter handling of second argument

Added by zverok (Victor Shepelev) about 1 year ago. Updated about 1 year ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:111818]

Description

Since Ruby 3.2 (#18788), the second argument to Regexp.new can be:

  1. Integer: then it is treated as a combination of Regexp::<constant> flags
  2. String: then it is treated as a combination of string flags
  3. nil or false: then it is ignored
  4. any other truthy value: then it is treated as an "ignore case" option.

The fourth one is confusing, especially since the introduction of the flexibility of flags: one might erroneously assume or forget the protocol, and the naive check will strengthen the assumption:

# maybe it accepts the array of string options?..
Regexp.new('foo', %w[i]) #=> /foo/i -- oh, seems it does

# would the symbol work?..
Regexp.new('foo', :i) #=> /foo/i -- awesome, it works!

I propose to change (4) to only handle literal true value, and raise TypeError on any unsupported type.

On compatibility: I believe that whenever the usage of boolean to distinguish "ignore case/respect case" is deliberate (like in rubygems), the code already passes true/false, not any random value. Otherwise, the change in Ruby 3.2 might also have broken it (what if it previously passed strings, meaning them to be "truthy values"?)

PS: BTW, the documentation for (4) was completely lost in Ruby 3.2, due to this PR. cc @jeremyevans0 (Jeremy Evans), @burdettelamar (Burdette Lamar)

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

It is already warned with $VERBOSE, and this make to raise ArgumentError.

diff --git a/re.c b/re.c
index 7a743185589..f03c2b48a1e 100644
--- a/re.c
+++ b/re.c
@@ -3866,7 +3866,7 @@ reg_extract_args(int argc, VALUE *argv, struct reg_init_args *args)
             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))
+            else if (!NIL_P(opts) && rb_bool_expected(opts, "ignorecase", TRUE))
                 flags = ONIG_OPTION_IGNORECASE;
         }
         if (!NIL_OR_UNDEF_P(n_flag)) {
Actions

Also available in: Atom PDF

Like0
Like0