From: blogger@... Date: 2021-02-23T00:23:09+00:00 Subject: [ruby-core:102575] [Ruby master Bug#17619] if false foo=42; end creates a foo local variable set to nil 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: