diff --git a/changelog/change_update_styleredundantsort_to_be_unsafe.md b/changelog/change_update_styleredundantsort_to_be_unsafe.md new file mode 100644 index 00000000000..ec4722dab88 --- /dev/null +++ b/changelog/change_update_styleredundantsort_to_be_unsafe.md @@ -0,0 +1 @@ +* [#10122](https://github.com/rubocop/rubocop/pull/10122): Update `Style/RedundantSort` to be unsafe, and revert the special case for `size` from [#10061](https://github.com/rubocop/rubocop/pull/10061). ([@dvandersluis][]) diff --git a/config/default.yml b/config/default.yml index 6e99897a826..9b9e61be563 100644 --- a/config/default.yml +++ b/config/default.yml @@ -4160,7 +4160,6 @@ Style/NumericLiteralPrefix: - zero_with_o - zero_only - Style/NumericLiterals: Description: >- Add underscores to large numeric literals to improve their @@ -4481,6 +4480,8 @@ Style/RedundantSort: `max_by` instead of `sort_by...last`, etc. Enabled: true VersionAdded: '0.76' + VersionChanged: <> + Safe: false Style/RedundantSortBy: Description: 'Use `sort` instead of `sort_by { |x| x }`.' diff --git a/lib/rubocop/cop/style/redundant_sort.rb b/lib/rubocop/cop/style/redundant_sort.rb index bf31a01c9fb..d0b0c6af758 100644 --- a/lib/rubocop/cop/style/redundant_sort.rb +++ b/lib/rubocop/cop/style/redundant_sort.rb @@ -12,6 +12,33 @@ module Style # `Enumerable#max_by` can replace `Enumerable#sort_by` calls # after which only the first or last element is used. # + # @safety + # This cop is unsafe, because `sort...last` and `max` may not return the + # same element in all cases. + # + # In an enumerable where there are multiple elements where `a <=> b == 0`, + # or where the transformation done by the `sort_by` block has the + # same result, `sort.last` and `max` (or `sort_by.last` and `max_by`) + # will return different elements. `sort.last` will return the last + # element but `max` will return the first element. + # + # For example: + # + # [source,ruby] + # ---- + # class MyString < String; end + # strings = [MyString.new('test'), 'test'] + # strings.sort.last.class #=> String + # strings.max.class #=> MyString + # ---- + # + # [source,ruby] + # ---- + # words = %w(dog horse mouse) + # words.sort_by { |word| word.length }.last #=> 'mouse' + # words.max_by { |word| word.length } #=> 'horse' + # ---- + # # @example # # bad # [2, 1, 3].sort.first