Issue #17619 has been updated by Student (Nathan Zook).


josh.cheek (Josh Cheek) wrote in #note-9:
> It's intentional. Eg what if you set the same variable in both branches? Then it would be clearer that you are expecting the variable to be visible outside the scope of the conditional.
> 
> Contrived code example:
> 
> ```ruby
> if eligible?
>   bonus = 100
> else
>   bonus = 0
> end
> score + bonus
> ```

In that case, I would expect code to flow down one block, which will define bonus, or the other, which will define bonus.

I had forgotten about this WAT.  To be honest, even reading the spec, I don't know that I would have expected non-executed code to have defined the variable.

Having said that, if you need to check later that a section of code was executed, checking against a variable being defined is surely setting a landmine for later programmers.

Let's check some history...

```ruby
if condition
  foo = 42
end
...
if defined?(foo)
...
```

v2:
```ruby
if condition
  foo = 42
end
...

if condition2
  foo = 6 * 9
end
...
if defined?(foo)
...
```

Just don't, unless you're implementing some sort of inspect or something...



----------------------------------------
Bug #17619: if false foo=42; end creates a foo local variable set to nil
https://bugs.ruby-lang.org/issues/17619#change-90559

* Author: pkmuldoon (Phil Muldoon)
* Status: Rejected
* Priority: Normal
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
Take this following code

```
[1] pry(main)> defined?(foo)
nil

[2] pry(main)> if false
[2] pry(main)*   foo = 42
[2] pry(main)* end  

[3] pry(main)> defined?(foo)
"local-variable"
```

The inner scope inherits the parent scope (ok) but also modifies the parent scope even if the child scope is never entered. A lesser effect of this:

```
[1] pry(main)> defined?(bar)
nil

[2] pry(main)> if false
[2] pry(main)*   bar = 99
[2] pry(main)* end  

[3] pry(main)> defined?(bar)
"local-variable"

[5] pry(main)> bar
99
```

That somewhat lesser affecting because I can just about accept a variable invading the parent scope, and existing after, as a hoisting event. But surely that should not be the case in the negative program-flow case?

The side effects of this are defined?(foo) can't be trusted anymore.

Apologies if this bug has been filed. I did search for it, but couldn't find anything quite matching it. Thanks!



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>