Ruby 2.4 Regexp#match? not polluting global variables

Rohit Kumar

By Rohit Kumar

on November 4, 2016

This blog is part of our  Ruby 2.4 series.

Ruby has many ways to match with a regular expression.

Regexp#===

It returns true/false and sets the $~ global variable.

1
2/stat/ === "case statements"
3#=> true
4$~
5#=> #<MatchData "stat">
6

Regexp#=~

It returns integer position it matched or nil if no match. It also sets the $~ global variable.

1
2/stat/ =~ "case statements"
3#=> 5
4$~
5#=> #<MatchData "stat">
6

Regexp#match

It returns match data and also sets the $~ global variable.

1
2/stat/.match("case statements")
3#=> #<MatchData "stat">
4$~
5#=> #<MatchData "stat">
6

Ruby 2.4 adds Regexp#match?

This new method just returns true/false and does not set any global variables.

1
2/case/.match?("case statements")
3#=> true

So Regexp#match? is good option when we are only concerned with the fact that regex matches or not.

Regexp#match? is also faster than its counterparts as it reduces object allocation by not creating a back reference and changing $~.

1
2require 'benchmark/ips'
3
4Benchmark.ips do |bench|
5
6  EMAIL_ADDR = 'disposable.style.email.with+symbol@example.com'
7  EMAIL_REGEXP_DEVISE = /\A[^@\s]+@([^@\s]+\.)+[^@\W]+\z/
8
9  bench.report('Regexp#===') do
10    EMAIL_REGEXP_DEVISE === EMAIL_ADDR
11  end
12
13  bench.report('Regexp#=~') do
14    EMAIL_REGEXP_DEVISE =~ EMAIL_ADDR
15  end
16
17  bench.report('Regexp#match') do
18    EMAIL_REGEXP_DEVISE.match(EMAIL_ADDR)
19  end
20
21  bench.report('Regexp#match?') do
22    EMAIL_REGEXP_DEVISE.match?(EMAIL_ADDR)
23  end
24
25  bench.compare!
26end
27
28#=> Warming up --------------------------------------
29#=>          Regexp#===   103.876k i/100ms
30#=>           Regexp#=~   105.843k i/100ms
31#=>        Regexp#match    58.980k i/100ms
32#=>       Regexp#match?   107.287k i/100ms
33#=> Calculating -------------------------------------
34#=>          Regexp#===      1.335M (± 9.5%) i/s -      6.648M in   5.038568s
35#=>           Regexp#=~      1.369M (± 6.7%) i/s -      6.880M in   5.049481s
36#=>        Regexp#match    709.152k (± 5.4%) i/s -      3.539M in   5.005514s
37#=>       Regexp#match?      1.543M (± 4.6%) i/s -      7.725M in   5.018696s
38#=>
39#=> Comparison:
40#=>       Regexp#match?:  1542589.9 i/s
41#=>           Regexp#=~:  1369421.3 i/s - 1.13x  slower
42#=>          Regexp#===:  1335450.3 i/s - 1.16x  slower
43#=>        Regexp#match:   709151.7 i/s - 2.18x  slower
44

If you liked this blog, you might also like the other blogs we have written. Check out the full archive.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, React.js, React Native, remote work,open source, engineering & design.