Class: RuboCop::Cop::Performance::CompareWithBlock

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
RangeHelp
Defined in:
lib/rubocop/cop/performance/compare_with_block.rb

Overview

Identifies places where ‘sort { |a, b| a.foo <=> b.foo }` can be replaced by `sort_by(&:foo)`. This cop also checks `sort!`, `min`, `max` and `minmax` methods.

Examples:

# bad
array.sort   { |a, b| a.foo <=> b.foo }
array.sort!  { |a, b| a.foo <=> b.foo }
array.max    { |a, b| a.foo <=> b.foo }
array.min    { |a, b| a.foo <=> b.foo }
array.minmax { |a, b| a.foo <=> b.foo }
array.sort   { |a, b| a[:foo] <=> b[:foo] }

# good
array.sort_by(&:foo)
array.sort_by!(&:foo)
array.sort_by { |v| v.foo }
array.sort_by do |var|
  var.foo
end
array.max_by(&:foo)
array.min_by(&:foo)
array.minmax_by(&:foo)
array.sort_by { |a| a[:foo] }

Constant Summary collapse

MSG =
'Use `%<replacement_method>s%<instead>s` instead of ' \
'`%<compare_method>s { |%<var_a>s, %<var_b>s| %<str_a>s ' \
'<=> %<str_b>s }`.'

Instance Method Summary collapse

Instance Method Details

#on_block(node) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rubocop/cop/performance/compare_with_block.rb', line 55

def on_block(node)
  compare?(node) do |send, var_a, var_b, body|
    replaceable_body?(body, var_a, var_b) do |method, args_a, args_b|
      return unless slow_compare?(method, args_a, args_b)

      range = compare_range(send, node)

      add_offense(range, message: message(send, method, var_a, var_b, args_a)) do |corrector|
        replacement = if method == :[]
                        "#{REPLACEMENT[send.method_name]} { |a| a[#{args_a.first.source}] }"
                      else
                        "#{REPLACEMENT[send.method_name]}(&:#{method})"
                      end
        corrector.replace(range, replacement)
      end
    end
  end
end