Class: RuboCop::Cop::Performance::RedundantEqualityComparisonBlock

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector, TargetRubyVersion
Defined in:
lib/rubocop/cop/performance/redundant_equality_comparison_block.rb

Overview

Checks for uses ‘Enumerable#all?`, `Enumerable#any?`, `Enumerable#one?`, and `Enumerable#none?` are compared with `===` or similar methods in block.

By default, ‘Object#===` behaves the same as `Object#==`, but this behavior is appropriately overridden in subclass. For example, `Range#===` returns `true` when argument is within the range.

This cop has ‘AllowRegexpMatch` option and it is true by default because `regexp.match?(’string’)‘ often used in block changes to the opposite result:

source,ruby

[/pattern/].all? { |regexp| regexp.match?(‘pattern’) } # => true [/pattern/].all? { |regexp| regexp =~ ‘pattern’ } # => true [/pattern/].all?(‘pattern’) # => false


Examples:

# bad
items.all? { |item| pattern === item }
items.all? { |item| item == other }
items.all? { |item| item.is_a?(Klass) }
items.all? { |item| item.kind_of?(Klass) }

# good
items.all?(pattern)
items.all?(Klass)

AllowRegexpMatch: true (default)


# good
items.all? { |item| item =~ pattern }
items.all? { |item| item.match?(pattern) }

AllowRegexpMatch: false


# bad
items.all? { |item| item =~ pattern }
items.all? { |item| item.match?(pattern) }

Constant Summary collapse

MSG =
'Use `%<prefer>s` instead of block.'
TARGET_METHODS =
%i[all? any? one? none?].freeze
COMPARISON_METHODS =
%i[== === is_a? kind_of?].freeze
REGEXP_METHODS =
%i[=~ match?].freeze
IS_A_METHODS =
%i[is_a? kind_of?].freeze

Instance Method Summary collapse

Instance Method Details

#on_block(node) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 62

def on_block(node)
  return unless TARGET_METHODS.include?(node.method_name)
  return unless one_block_argument?(node.arguments)

  block_argument = node.first_argument
  block_body = node.body
  return unless use_equality_comparison_block?(block_body)
  return if same_block_argument_and_is_a_argument?(block_body, block_argument)
  return unless (new_argument = new_argument(block_argument, block_body))

  range = offense_range(node)
  prefer = "#{node.method_name}(#{new_argument})"

  add_offense(range, message: format(MSG, prefer: prefer)) do |corrector|
    corrector.replace(range, prefer)
  end
end