Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new Style/HashExcept cop #9283

Merged
merged 1 commit into from
Dec 25, 2020

Conversation

koic
Copy link
Member

@koic koic commented Dec 23, 2020

This PR adds new Style/HashExcept cop.

This cop checks for usages of Hash#reject and Hash#select methods that can be replaced with Hash#except method.

This cop should only be enabled on Ruby version 3.0 or higher.
(Hash#except was added in Ruby 3.0.)

# bad
{foo: 1, bar: 2, baz: 3}.reject {|k, v| k == :bar }
{foo: 1, bar: 2, baz: 3}.select {|k, v| k != :bar }

# good
{foo: 1, bar: 2, baz: 3}.except(:bar)

cf. https://bugs.ruby-lang.org/issues/15822


Before submitting the PR make sure the following are checked:

  • The PR relates to only one subject with a clear title and description in grammatically correct, complete sentences.
  • Wrote good commit messages.
  • Commit message starts with [Fix #issue-number] (if the related issue exists).
  • Feature branch is up-to-date with master (if not - rebase it).
  • Squashed related commits together.
  • Added tests.
  • Ran bundle exec rake default. It executes all tests and runs RuboCop on its own code.
  • Added an entry (file) to the changelog folder named {change_type}_{change_description}.md if the new code introduces user-observable changes. See changelog entry format for details.

@marcandre
Copy link
Contributor

You're fast 😆

Technically, it's only if using eql? that they are equivalent.

{0 => :foo}.except(0.0)
# => {0=>:foo}
{0 => :foo}.reject {|k, v| k == 0.0 }
# => {}

Maybe if running in safe mode we should be more careful, so k == :symbol and k.eql? 0 is ok but not k == var?

@koic koic force-pushed the add_new_style_hash_except_cop branch from 7ac8d16 to 38c767d Compare December 24, 2020 03:55
@koic
Copy link
Member Author

koic commented Dec 24, 2020

Oh, I couldn't catch it! I prefer being safe, so I updated this PR that way! For safe detection, it is limited to commonly used string and symbol comparisons when used ==. Thank you always!

minimum_target_ruby_version 3.0

MSG = 'Use `%<prefer>s` instead.'
RESTRICT_ON_SEND = %i[reject select].freeze
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you forgot about filter, keep_if and delete_if. I don't use those Hash methods often, but I recall there were a ton of aliases there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added filter method. On the other hand, delete_if and keep_if methods are not checked because they are incompatible with except method.

# except
h = {foo: 1, bar: 2, baz: 3}
=> {:foo=>1, :bar=>2, :baz=>3}
h.except(:bar)
=> {:foo=>1, :baz=>3}
h
=> {:foo=>1, :bar=>2, :baz=>3}

# delete_if
h = {foo: 1, bar: 2, baz: 3}
=> {:foo=>1, :bar=>2, :baz=>3}
h.delete_if {|k, v| k == :bar }
=> {:foo=>1, :baz=>3}
h
=> {:foo=>1, :baz=>3}

# keep_if
h = {foo: 1, bar: 2, baz: 3}
=> {:foo=>1, :bar=>2, :baz=>3}
h.keep_if {|k, v| k != :bar }
=> {:foo=>1, :baz=>3}
h
=> {:foo=>1, :baz=>3}

I updated documentation and test on this.

@koic koic force-pushed the add_new_style_hash_except_cop branch from 38c767d to 678f147 Compare December 25, 2020 02:56
This PR adds new `Style/HashExcept` cop.

This cop checks for usages of `Hash#reject`, `Hash#select`, and `Hash#filter` methods
that can be replaced with `Hash#except` method.

This cop should only be enabled on Ruby version 3.0 or higher.
(`Hash#except` was added in Ruby 3.0.)

```ruby
# bad
{foo: 1, bar: 2, baz: 3}.reject {|k, v| k == :bar }
{foo: 1, bar: 2, baz: 3}.select {|k, v| k != :bar }

# good
{foo: 1, bar: 2, baz: 3}.except(:bar)
```

cf. https://bugs.ruby-lang.org/issues/15822
@koic koic force-pushed the add_new_style_hash_except_cop branch from 678f147 to 6166df3 Compare December 25, 2020 03:07
@bbatsov bbatsov merged commit bee3bb5 into rubocop:master Dec 25, 2020
@bbatsov
Copy link
Collaborator

bbatsov commented Dec 25, 2020

Thanks!

@koic koic deleted the add_new_style_hash_except_cop branch December 25, 2020 07:09
@luke-hill
Copy link

luke-hill commented Mar 5, 2021

@koic Question about this new cop.

I've noticed this pulling through on ruby 2.7 - However it's pulling through as Rails/ - I'm guessing this method is something which was added to the raw ruby implementation in ruby 3.0 (Previously I'm guessing it was in AS?)

Just saw the ruby lang implementation for ruby 2.7 - So I'm just guessing this was in AS before that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants