Skip to content

Style/CollectionCompact: bug in auto correction #12801

@gongfarmer

Description

@gongfarmer

The cop Style/CollectionCompact has unsafe autocorrect which changes calls to Hash#delete_if to Hash#compact.
This is incorrect because Hash#delete_if modifies the object and Hash#compact does not.
The correct replacement would be Hash#compact! (the ! version).

The same applies to Array#delete_if erroneously being converted to Array#compact.
My reproduction below only shows the Hash case. I have not gone looking for other Array / Hash methods that modify the receiver.

Warning: Array#delete_if returns self after modifying the object. Array#compact! sometimes returns nil:
`
$ ri --no-pager Array#compact!
Array#compact!

(from ruby core)

array.compact! -> self or nil

Removes all nil elements from self.

Returns self if any elements removed, otherwise nil.
So maybe it is not as simple as just changingcompacttocompact!` in the replacement.


Expected behavior

I expect a call to Hash#delete_if to be replaced with Hash#compact! (the ! version)

Actual behavior

Hash#delete_if is replaced with Hash#compact (the non ! version)

Steps to reproduce the problem

Example input:

#!/usr/bin/ruby
h = {
  a: "a",
  b: "b",
  c: nil,
}
h.delete_if { |_, v| v.nil? }
pp h

This prints the following:

$ ruby test.rb
{:a=>"a", :b=>"b"}

After letting rubocop correct the source file, the output has changed:

$ rubocop -c /dev/null test.rb  --only Style/CollectionCompact -A
Inspecting 1 file
C

Offenses:

test.rb:8:3: C: [Corrected] Style/CollectionCompact: Use compact instead of delete_if { |_, v| v.nil? }.
h.delete_if { |_, v| v.nil? }
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^

1 file inspected, 1 offense detected, 1 offense corrected

$ ruby test.rb
{:a=>"a", :b=>"b", :c=>nil}

RuboCop version

$ rubocop -V
1.62.1 (using Parser 3.3.0.5, rubocop-ast 1.31.2, running on ruby 3.1.2) +server [x86_64-linux-gnu]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy