How is a local variable created even when IF condition evaluates to false in Ruby?

ruby, variables

Solution

Local variables in ruby are created during parsing/compilation of code (not execution). They are lexically scoped, so a local variable is not visible before the line where it's assigned to.

defined?(foo) # => nil
if false
  defined?(foo) # => 
  foo = 'blah'
  defined?(foo) # => 
end

defined?(foo) # => "local-variable"
foo # => nil

`defined?(foo)` lines inside of `if` return nothing, because they didn't run. The assignment wasn't executed as well. However, the compiler saw the assignment to local variable and created one (with default value of `nil`).

This behaviour explains the trick from WAT talk:

a = a # => nil

Even though variable `a` doesn't exist, it is created (and set to nil) right before this line, simply because there is an assignment expression in the code (target of which is yet unknown local variable). So by the time the right hand side of this expression is evaluated, `a` exists.

Problem

Try the following in irb: (I'm using Ruby 2.0.0-p247) ``` blah #=> NameError: undefined local variable or method `blah' for main:Object if false blah = 'blah' end #=> nil blah #=> nil ``` I'm surprised that `blah` is assigned `nil` even when the `if` condition evaluates to `false`. I thought the code within `if` is skipped as the condition evaluates to `false`. Could someone with Ruby internals knowledge kindly explain how this happened? Thank you

Original source

Related problems