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