@@ -10,22 +10,42 @@ module Performance
10
10
# behavior is appropriately overridden in subclass. For example,
11
11
# `Range#===` returns `true` when argument is within the range.
12
12
#
13
+ # This cop has `AllowRegexpMatch` option and it is false by default because
14
+ # `regexp.match?('string')` often used in block changes to the opposite result:
15
+ #
16
+ # [source,ruby]
17
+ # ----
18
+ # [/pattern/].all? { |regexp| regexp.match?('pattern') } # => true
19
+ # [/pattern/].all? { |regexp| regexp =~ 'pattern' } # => true
20
+ # [/pattern/].all?('pattern') # => false
21
+ # ----
22
+ #
13
23
# @safety
14
24
# This cop is unsafe because `===` and `==` do not always behave the same.
15
25
#
16
26
# @example
17
27
# # bad
18
28
# items.all? { |item| pattern === item }
19
29
# items.all? { |item| item == other }
20
- # items.all? { |item| item =~ pattern }
21
30
# items.all? { |item| item.is_a?(Klass) }
22
31
# items.all? { |item| item.kind_of?(Klass) }
23
- # items.all? { |item| item.match?(pattern) }
24
32
#
25
33
# # good
26
34
# items.all?(pattern)
27
35
# items.all?(Klass)
28
36
#
37
+ # @example AllowRegexpMatch: true (default)
38
+ #
39
+ # # good
40
+ # items.all? { |item| item =~ pattern }
41
+ # items.all? { |item| item.match?(pattern) }
42
+ #
43
+ # @example AllowRegexpMatch: false
44
+ #
45
+ # # bad
46
+ # items.all? { |item| item =~ pattern }
47
+ # items.all? { |item| item.match?(pattern) }
48
+ #
29
49
class RedundantEqualityComparisonBlock < Base
30
50
extend AutoCorrector
31
51
extend TargetRubyVersion
@@ -35,7 +55,8 @@ class RedundantEqualityComparisonBlock < Base
35
55
MSG = 'Use `%<prefer>s` instead of block.'
36
56
37
57
TARGET_METHODS = %i[ all? any? one? none? ] . freeze
38
- COMPARISON_METHODS = %i[ == === =~ is_a? kind_of? match? ] . freeze
58
+ COMPARISON_METHODS = %i[ == === is_a? kind_of? ] . freeze
59
+ REGEXP_METHODS = %i[ =~ match? ] . freeze
39
60
IS_A_METHODS = %i[ is_a? kind_of? ] . freeze
40
61
41
62
def on_block ( node )
@@ -63,7 +84,11 @@ def one_block_argument?(block_arguments)
63
84
end
64
85
65
86
def use_equality_comparison_block? ( block_body )
66
- block_body . send_type? && COMPARISON_METHODS . include? ( block_body . method_name )
87
+ return false unless block_body . send_type?
88
+
89
+ method_name = block_body . method_name
90
+
91
+ COMPARISON_METHODS . include? ( method_name ) || ( !allow_regexp_match? && REGEXP_METHODS . include? ( method_name ) )
67
92
end
68
93
69
94
def same_block_argument_and_is_a_argument? ( block_body , block_argument )
@@ -102,6 +127,10 @@ def use_block_argument_in_method_argument_of_operand?(block_argument, operand)
102
127
def offense_range ( node )
103
128
node . send_node . loc . selector . join ( node . source_range . end )
104
129
end
130
+
131
+ def allow_regexp_match?
132
+ cop_config . fetch ( 'AllowRegexpMatch' , true )
133
+ end
105
134
end
106
135
end
107
136
end
0 commit comments