Skip to content

Commit 26a442b

Browse files
committed
[GR-45621] Accept options argument to Regexp#{new,compile} of String
PullRequest: truffleruby/4138
2 parents 9270244 + a2dd42b commit 26a442b

File tree

6 files changed

+51
-21
lines changed

6 files changed

+51
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Compatibility:
3737
* Implement `Class#attached_object` method (#3039, @andrykonchin).
3838
* Fix `ENV#{clone,dup}` and raise `TypeError` (#3039, @andrykonchin).
3939
* Fix `Coverage.supported?` and raise `TypeError` if argument is not Symbol (#3039, @andrykonchin).
40+
* Accept options argument to `Regexp.{new,compile}` of String and warn for unknown types (#3039, @rwstauner).
4041

4142
Performance:
4243

spec/ruby/core/regexp/shared/new.rb

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,30 @@ def obj.to_str() [] end
123123
(r.options & Regexp::EXTENDED).should_not == 0
124124
end
125125

126-
it "does not try to convert the second argument to Integer with #to_int method call" do
127-
ScratchPad.clear
128-
obj = Object.new
129-
def obj.to_int() ScratchPad.record(:called) end
126+
ruby_version_is ""..."3.2" do
127+
it "does not try to convert the second argument to Integer with #to_int method call" do
128+
ScratchPad.clear
129+
obj = Object.new
130+
def obj.to_int() ScratchPad.record(:called) end
131+
132+
Regexp.send(@method, "Hi", obj)
130133

131-
Regexp.send(@method, "Hi", obj)
134+
ScratchPad.recorded.should == nil
135+
end
136+
end
132137

133-
ScratchPad.recorded.should == nil
138+
ruby_version_is "3.2" do
139+
it "does not try to convert the second argument to Integer with #to_int method call" do
140+
ScratchPad.clear
141+
obj = Object.new
142+
def obj.to_int() ScratchPad.record(:called) end
143+
144+
-> {
145+
Regexp.send(@method, "Hi", obj)
146+
}.should complain(/expected true or false as ignorecase/, {verbose: true})
147+
148+
ScratchPad.recorded.should == nil
149+
end
134150
end
135151

136152
ruby_version_is ""..."3.2" do
@@ -188,12 +204,12 @@ def obj.to_int() ScratchPad.record(:called) end
188204
end
189205

190206
it "raises an Argument error if the second argument contains unsupported chars" do
191-
-> { Regexp.send(@method, 'Hi', 'e') }.should raise_error(ArgumentError)
192-
-> { Regexp.send(@method, 'Hi', 'n') }.should raise_error(ArgumentError)
193-
-> { Regexp.send(@method, 'Hi', 's') }.should raise_error(ArgumentError)
194-
-> { Regexp.send(@method, 'Hi', 'u') }.should raise_error(ArgumentError)
195-
-> { Regexp.send(@method, 'Hi', 'j') }.should raise_error(ArgumentError)
196-
-> { Regexp.send(@method, 'Hi', 'mjx') }.should raise_error(ArgumentError)
207+
-> { Regexp.send(@method, 'Hi', 'e') }.should raise_error(ArgumentError, "unknown regexp option: e")
208+
-> { Regexp.send(@method, 'Hi', 'n') }.should raise_error(ArgumentError, "unknown regexp option: n")
209+
-> { Regexp.send(@method, 'Hi', 's') }.should raise_error(ArgumentError, "unknown regexp option: s")
210+
-> { Regexp.send(@method, 'Hi', 'u') }.should raise_error(ArgumentError, "unknown regexp option: u")
211+
-> { Regexp.send(@method, 'Hi', 'j') }.should raise_error(ArgumentError, "unknown regexp option: j")
212+
-> { Regexp.send(@method, 'Hi', 'mjx') }.should raise_error(ArgumentError, /unknown regexp option: mjx\b/)
197213
end
198214
end
199215

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
11
fails(immutable regexp):Regexp.compile works by default for subclasses with overridden #initialize
2-
fails:Regexp.compile given a String warns any non-Integer, non-nil, non-false second argument
3-
fails:Regexp.compile given a String accepts a String of supported flags as the second argument
4-
fails:Regexp.compile given a String raises an Argument error if the second argument contains unsupported chars

spec/tags/core/regexp/new_tags.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
11
fails(immutable regexp):Regexp.new works by default for subclasses with overridden #initialize
2-
fails:Regexp.new given a String warns any non-Integer, non-nil, non-false second argument
3-
fails:Regexp.new given a String accepts a String of supported flags as the second argument
4-
fails:Regexp.new given a String raises an Argument error if the second argument contains unsupported chars

src/main/ruby/truffleruby/core/regexp.rb

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,28 @@ def self.new(pattern, opts = undefined, encoding = nil)
144144

145145
if Primitive.is_a?(opts, Integer)
146146
opts = opts & (OPTION_MASK | KCODE_MASK) if opts > 0
147-
elsif !Primitive.undefined?(opts) && opts
148-
opts = IGNORECASE
147+
elsif Primitive.is_a?(opts, String)
148+
opts = opts.chars.reduce(0) do |result, char|
149+
case char
150+
when 'i'
151+
result | IGNORECASE
152+
when 'm'
153+
result | MULTILINE
154+
when 'x'
155+
result | EXTENDED
156+
else
157+
raise ArgumentError, "unknown regexp option: #{opts}"
158+
end
159+
end
160+
elsif !Primitive.undefined?(opts)
161+
# Valid values are true, false, nil.
162+
# Other values warn but treat as true.
163+
if Primitive.false?(opts) || Primitive.nil?(opts)
164+
opts = 0
165+
else
166+
warn "expected true or false as ignorecase: #{opts}" unless Primitive.true?(opts)
167+
opts = IGNORECASE
168+
end
149169
else
150170
opts = 0
151171
end

test/mri/excludes/TestRegexp.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
exclude :test_rindex_regexp, "needs investigation"
3838
exclude :test_yoshidam_net_20041111_1, "needs investigation"
3939
exclude :test_match_control_meta_escape, "<0> expected but was"
40-
exclude :test_initialize_option, "<//m> expected but was"
4140
exclude :test_initialize_bool_warning, "expected: /expected true or false as ignorecase/"
4241
exclude :test_linear_time_p, "NoMethodError: undefined method `linear_time?' for Regexp:Class"
4342
exclude :test_extended_comment_invalid_escape_bug_18294, "assert_separately failed with error message"

0 commit comments

Comments
 (0)