Project

General

Profile

Actions

Feature #18788

closed

Support passing Regexp options as String to Regexp.new

Added by janosch-x (Janosch Müller) almost 2 years ago. Updated almost 2 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:108590]

Description

Current situation

Regexp.new takes an integer as second argument which needs to be ORed together from multiple constants:

Regexp.new('foo', Regexp::IGNORECASE | Regexp::MULTILINE | Regexp::EXTENDED) # => /foo/imx

Any other non-nil value is treated as i flag:

Regexp.new('foo', Object.new) # => /foo/i

Suggestion

Regexp.new should support passing the regexp flags not only as an Integer, but also as a String, like so:

Regexp.new('foo', 'i')   # => /foo/i
Regexp.new('foo', 'imx') # => /foo/imx

# edge cases
Regexp.new('foo', 'iii') # => /foo/i
Regexp.new('foo', '')    # => /foo/

# unsupported flags should probably emit a warning
Regexp.new('foo', 'jmq') # => /foo/m
Regexp.new('foo', '-m')  # => /foo/m

Reasons

  1. The constants are a bit cumbersome to use, particularly when building the regexp from variable data:
def make_regexp(regexp_body, opt_string)
  opt_int = 0
  opt_int |= Regexp::IGNORECASE if opt_string.include?('i')
  opt_int |= Regexp::MULTILINE  if opt_string.include?('m')
  opt_int |= Regexp::EXTENDED   if opt_string.include?('x')

  Regexp.new(regexp_body, opt_int)
end
  1. Passing a String is already silently accepted, and people might get the wrong impression that it works:
Regexp.new('foo', 'i') # => /foo/i

... but it doesn't really work:

Regexp.new('foo', 'x') # => /foo/i

Backwards compatibility

This change would not be fully backwards compatible.

Code that relies on the second argument being a String which does not contain "i" in order to make the Regexp case insensitive would break.

Note: originally I suggested supporting Symbols in the same way as Strings, but removed that in light of the discussion.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0