0

Hi I got a variable inside an if block that the condition of if is false.

if false
  a = 1
end

a => nil

However the a does not raise an NoMethodError instead returns nil?

Juanito Fatas
  • 9,419
  • 9
  • 46
  • 70

2 Answers2

1

Why a = 1 Isn't Evaluated

Your code is logically equivalent to both of the following:

  • a = 1 if false; a
  • false.eql?(true) && a=(1)

In all three cases, since false is not true, variable a is never assigned. However, the reason it's nil rather than raising NameError is a little non-intuitive.

Why Unassigned Variables Return nil Instead of Raising NameError

In Ruby, non-constant variables are defined when encountered by the parser, rather then when executed by the code path. If the parser encounters a non-constant variable that is not an assignment, it creates the variable and assigns nil to it.

You can still expect to see NameError when the interpreter uses an unassigned variable. For example, in a fresh irb session:

# variable not in scope
puts a
#=> NameError (undefined local variable or method `a' for main:Object)

# variable auto-vivified by parser
a = 1 if false; a
#=> nil

a = 1; a
#=> 1

Related

Why are constants not initialized like local variables when the file is parsed by Ruby?

Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
0

The Ruby parser keeps track of which names are local variables (vs method calls). Ruby parser doesn’t know if the conditionals will be true/false, so it already got an reference to a.

Juanito Fatas
  • 9,419
  • 9
  • 46
  • 70