rubocop / rubocop

A Ruby static code analyzer and formatter, based on the community Ruby style guide.

Home Page:https://docs.rubocop.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`Lint/ShadowingOuterLocalVariable` does not take into account `if`/`else` branches

postmodern opened this issue · comments

Lint/ShadowingOuterLocalVariable appears to be incorrectly flagging using of a local variable in one branch of an if/else statement, where the other branch re-uses the same variable name for a block variable. Since only one of the if/else branches can ever execute, this should not cause any problems.

Steps To Reproduce

Gemfile:

source 'https://rubygems.org'

gem 'rubocop'
def test(obj, first: false)
  if first
    if (thing = get_first_thing(obj))
      print_thing(thing)
      yield thing
    end
  else
    get_things(obj) do |thing|
      print_thing(thing)
      yield thing
    end
  end
end

Expected behavior

No warnings.

Actual behavior

test.rb:8:25: W: Lint/ShadowingOuterLocalVariable: Shadowing outer local variable - thing.
    get_things(obj) do |thing|
                        ^^^^^

RuboCop version

$ bundle exec rubocop -V
1.63.4 (using Parser 3.3.1.0, rubocop-ast 1.31.2, running on ruby 3.2.4) [x86_64-linux]

It has come to my attention that Ruby will define local variables even in branches that are not executed.

def test
  if false
    x = 1
  else
  end
  local_variables
end

test
# => [:x]

So rubocop is technically correct here.