-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
In certain situations, RuboCop incorrectly identifies arguments as being "shadowed by a local variable before it was used."
Take this example method that downloads a file if certain conditions are met, and then returns whether the file was downloaded or not
# target_exists: whether the target file exists or not. If it doesn't exist, we must download
# other_conditions_met: if these conditions are met and the file exists, skip the download
# skip_download: don't download, even if `other_conditions_met` is true. However, always download if `target_exists` is false
def download_to_target?(endpoint, target_exists:, other_conditions_met:, skip_download: false)
skip_download = false unless target_exists
skip_download ||= target_exists && other_conditions_met
begin
puts "Downloading file #{endpoint}" unless skip_download
rescue StandardError
skip_download = false
end
!skip_download
endNormally, the download process is skipped if target_exists and other_conditions_met. The skip_download argument is used to override other_conditions_met, and skip the download even if those conditions are false. However, we never want to allow skipping the download if target_exists is false.
The effect of skip_download is demonstrated here:
$ bin/console
irb(main):001> download_to_target? "foo.txt", target_exists: true, other_conditions_met: false, skip_download: false
Downloading file foo.txt
=> true
irb(main):002> download_to_target? "foo.txt", target_exists: true, other_conditions_met: false, skip_download: true
=> falseAs you can see, modifying skip_download has an effect on the output. However, rubocop gives the following message:
$ bundle exec rubocop
Inspecting 8 files
...W....
Offenses:
lib/rubocop/test.rb:13:78: W: Lint/ShadowedArgument: Argument skip_download was shadowed by a local variable before it was used.
def download_to_target?(endpoint, target_exists:, other_conditions_met:, skip_download: false)
^^^^^^^^^^^^^^^^^^^^
8 files inspected, 1 offense detectedI believe this is incorrect, because as shown in the console output above, passing different values to skip_download returns a different result, indicating that skip_download is not actually shadowed.
Expected behavior
No RuboCop violations
Actual behavior
$ bundle exec rubocop --debug
For /Users/rylanpolster/Desktop/rubocop-test: configuration from /Users/rylanpolster/Desktop/rubocop-test/.rubocop.yml
Use parallel by default.
Running parallel inspection
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/6cb3c8aa5d0a05ad7ae243b17f0c0ebfe575bbaf
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/58bb370c1ae436abce2481ae7f2faaf723af28bc
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/14c9461f0e85c5bba9e1a207e916ec1318c1a7d6
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/251face88f94ebec482a3320c71fedb341db40c6
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/46f5f04a2f99cf23d920e6e24fc4aea8caab1eeb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/278c4c969bf9a250ce7dea8a0a74a2489e9948c4
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/30efeb7f71f0ff8b0eac9f82e5d911ebcaa5a2ae
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/79fa9b3dc047bc6568f24fd1af5f3b8bbae7a04e
Inspecting 8 files
Scanning /Users/rylanpolster/Desktop/rubocop-test/Gemfile
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/251face88f94ebec482a3320c71fedb341db40c6
.Scanning /Users/rylanpolster/Desktop/rubocop-test/Rakefile
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/46f5f04a2f99cf23d920e6e24fc4aea8caab1eeb
.Scanning /Users/rylanpolster/Desktop/rubocop-test/bin/console
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/58bb370c1ae436abce2481ae7f2faaf723af28bc
.Scanning /Users/rylanpolster/Desktop/rubocop-test/lib/rubocop/test.rb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/6cb3c8aa5d0a05ad7ae243b17f0c0ebfe575bbaf
WScanning /Users/rylanpolster/Desktop/rubocop-test/lib/rubocop/test/version.rb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/278c4c969bf9a250ce7dea8a0a74a2489e9948c4
.Scanning /Users/rylanpolster/Desktop/rubocop-test/rubocop-test.gemspec
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/30efeb7f71f0ff8b0eac9f82e5d911ebcaa5a2ae
.Scanning /Users/rylanpolster/Desktop/rubocop-test/spec/rubocop/test_spec.rb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/14c9461f0e85c5bba9e1a207e916ec1318c1a7d6
.Scanning /Users/rylanpolster/Desktop/rubocop-test/spec/spec_helper.rb
Loading cache from /Users/rylanpolster/.cache/rubocop_cache/2c9471a62bcb70567f347d769fb45cd0173313ed/6d7a3b621ca1730e04accd938619e4bdab66cfb1/79fa9b3dc047bc6568f24fd1af5f3b8bbae7a04e
.
Offenses:
lib/rubocop/test.rb:13:78: W: Lint/ShadowedArgument: Argument skip_download was shadowed by a local variable before it was used.
def download_to_target?(endpoint, target_exists:, other_conditions_met:, skip_download: false)
^^^^^^^^^^^^^^^^^^^^
8 files inspected, 1 offense detected
Finished in 0.1190679999999702 secondsSteps to reproduce the problem
Run RuboCop on this method:
def download_to_target?(endpoint, target_exists:, other_conditions_met:, skip_download: false)
skip_download = false unless target_exists
skip_download ||= target_exists && other_conditions_met
begin
puts "Downloading file #{endpoint}" unless skip_download
rescue StandardError
skip_download = false
end
!skip_download
endRuboCop version
$ bundle exec rubocop -V
1.80.1 (using Parser 3.3.9.0, rubocop-ast 1.46.0, analyzing as Ruby 3.1, running on ruby 3.4.4) +server [arm64-darwin24]