BigBinary Blog

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

Ruby 2.4 Regexp#match? not polluting global variables

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
Rohit Kumar in Ruby 2.4
November 4, 2016
Share

Subscribe to our newsletter