Skip to content

Commit

Permalink
Merge pull request #12543 from koic/fix_false_positives_for_style_has…
Browse files Browse the repository at this point in the history
…h_each_methods

[Fix #12540] Fix false positives for `Style/HashEachMethods`
  • Loading branch information
koic committed Dec 15, 2023
2 parents baa4a97 + 431b319 commit 58223eb
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#12540](https://github.com/rubocop/rubocop/issues/12540): Fix false positives for `Style/HashEachMethods` when rest block argument of `Enumerable#each` method is used. ([@koic][])
6 changes: 3 additions & 3 deletions lib/rubocop/cop/style/hash_each_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ def unused_block_arg_exist?(node, block_arg)
lvar_sources = node.body.each_descendant(:lvar).map(&:source)

if block_arg.mlhs_type?
block_arg.each_descendant(:arg).all? do |block_arg|
lvar_sources.none?(block_arg.source)
block_arg.each_descendant(:arg, :restarg).all? do |block_arg|
lvar_sources.none?(block_arg.source.delete_prefix('*'))
end
else
lvar_sources.none?(block_arg.source)
lvar_sources.none?(block_arg.source.delete_prefix('*'))
end
end

Expand Down
38 changes: 38 additions & 0 deletions spec/rubocop/cop/style/hash_each_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@
expect_no_offenses('foo.each { |(_, k), v| do_something(k, v) }')
end

it 'does not register an offense when the destructed rest value block arguments of `Enumerable#each` method are used' do
expect_no_offenses('foo.each { |k, (_, *v)| do_something(k, *v) }')
end

it 'does not register an offense when the destructed rest key block arguments of `Enumerable#each` method are used' do
expect_no_offenses('foo.each { |(_, *k), v| do_something(*k, v) }')
end

it 'does not register an offense when the single block argument of `Enumerable#each` method is used' do
expect_no_offenses('foo.each { |e| do_something(e) }')
end
Expand All @@ -89,6 +97,36 @@
expect_no_offenses('foo.each { |(k, v)| do_something(e) }')
end

it 'does not register an offense when the rest value block argument of `Enumerable#each` method is used' do
expect_no_offenses('foo.each { |k, *v| do_something(k, *v) }')
end

it 'does not register an offense when the rest key block argument of `Enumerable#each` method is used' do
expect_no_offenses('foo.each { |*k, v| do_something(*k, v) }')
end

it 'registers an offense when the rest value block argument of `Enumerable#each` method is unused' do
expect_offense(<<~RUBY)
foo.each { |k, *v| do_something(*v) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `each_value` instead of `each` and remove the unused `k` block argument.
RUBY

expect_correction(<<~RUBY)
foo.each_value { |*v| do_something(*v) }
RUBY
end

it 'registers an offense when the rest key block argument of `Enumerable#each` method is unused' do
expect_offense(<<~RUBY)
foo.each { |*k, v| do_something(*k) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `each_key` instead of `each` and remove the unused `v` block argument.
RUBY

expect_correction(<<~RUBY)
foo.each_key { |*k| do_something(*k) }
RUBY
end

it 'registers an offense when the value block argument of `Enumerable#each` method is unused' do
expect_offense(<<~RUBY)
foo.each { |k, unused_value| do_something(k) }
Expand Down

0 comments on commit 58223eb

Please sign in to comment.