class RuboCop::Cop::Performance::RedundantMatch
return value unless regex =~ ‘str’
method(str =~ /regex/)
# good
end
do_something
while regex.match(‘str’)
do_something if str.match(/regex/)
# bad
@example
index/‘nil` and is more performant.
returns `#<MatchData>`/`nil`. The return value of `=~` is an integral
Identifies the use of `Regexp#match` or `String#match`, which
def autocorrect(corrector, node)
def autocorrect(corrector, node) new_source = "#{node.receiver.source} =~ #{replacement(node)}" corrector.replace(node, new_source) end
def autocorrectable?(node)
def autocorrectable?(node) # Regexp#match can take a second argument, but this cop doesn't # register an offense in that case node.receiver.regexp_type? || node.first_argument.regexp_type? end
def call_like?(arg)
def call_like?(arg) arg.type?(:call, :yield, :super) end
def on_send(node)
def on_send(node) return unless match_call?(node) && (!node.value_used? || only_truthiness_matters?(node)) && !(node.parent && node.parent.block_type?) add_offense(node) do |corrector| autocorrect(corrector, node) if autocorrectable?(node) end end
def replacement(node)
def replacement(node) arg = node.first_argument if requires_parentheses?(arg) "(#{arg.source})" else arg.source end end
def requires_parentheses?(arg)
def requires_parentheses?(arg) return true if arg.if_type? && arg.ternary? return true if arg.operator_keyword? || arg.range_type? call_like?(arg) && requires_parentheses_for_call_like?(arg) end
def requires_parentheses_for_call_like?(arg)
def requires_parentheses_for_call_like?(arg) return false if arg.parenthesized? || !arg.arguments? !HIGHER_PRECEDENCE_OPERATOR_METHODS.include?(arg.method_name) end