class RuboCop::Cop::Performance::Casecmp
‘abc’.casecmp(str).zero?
str.casecmp(‘ABC’).zero?
@good
str.downcase == str.downcase
’ABC’.eql? str.upcase
’abc’ == str.downcase
str.upcase.eql? ‘ABC’
str.downcase == ‘abc’
@bad
@example
can better be implemented using ‘casecmp`.
This cop identifies places where a case-insensitive string comparison
def autocorrect(node)
def autocorrect(node) downcase_eq(node) do receiver, method, arg = *node variable, = *receiver return correction(node, receiver, method, arg, variable) end eq_downcase(node) do arg, method, receiver = *node variable, = *receiver return correction(node, receiver, method, arg, variable) end end
def correction(node, _receiver, method, arg, variable)
def correction(node, _receiver, method, arg, variable) lambda do |corrector| corrector.insert_before(node.loc.expression, '!') if method == :!= # we want resulting call to be parenthesized # if arg already includes one or more sets of parens, don't add more # or if method call already used parens, again, don't add more replacement = if arg.send_type? || !parentheses?(arg) "#{variable.source}.casecmp(#{arg.source}).zero?" else "#{variable.source}.casecmp#{arg.source}.zero?" end corrector.replace(node.loc.expression, replacement) end end
def on_send(node)
def on_send(node) return if part_of_ignored_node?(node) downcase_eq(node) do |send_downcase, case_method, eq_method, other| *_, method = *other if CASE_METHODS.include?(method) range = node.loc.expression ignore_node(node) else range = node.loc.selector.join(send_downcase.loc.selector) end add_offense(node, range, format(MSG, case_method, eq_method)) return end eq_downcase(node) do |eq_method, send_downcase, case_method| range = node.loc.selector.join(send_downcase.loc.selector) add_offense(node, range, format(MSG, eq_method, case_method)) end end