Variable hoisting in Ruby

Barney Kim
1 min readMar 22, 2018

--

A few days ago, I found a strange thing to look at the code of my colleagues. The code that caused the error was working well. Through a few experiments and searches, I came to know a new fact that I did not know about Ruby.

Bit of Weirdness

puts x

When we run this code, we will get an error obviously.

NameError: undefined local variable or method `x' for main:Object

Next, try this:

if true
x = 1
end
puts x

Output 1 as expected. Now, let’s try:

if false
x = 1
end
puts x

What are the results? An error? Or nil? Or maybe 1? Unlike the expectation that an error will occur, you can see that nil is printed. What’s going on?

Hoisting

The “magic” here is done by Ruby’s parser. when the parser runs over the if-clause it ‘hoists’ each variable to the top of its scope, declaring and setting it to nil, regardless of whether it will actually be executed. After that the interpreter figure out if the x = 1 line will ever get executed.

Summary

The local variable is created when the parser encounters the assignment, not when the assignment occurs:

a = 0 if false # does not assign to ap local_variables # prints [:a, :_]p a # prints nil

Don’t confuse the parser with the interpreter.

--

--

Barney Kim

Software Engineer@KakaoMobility, Self-Driving Car Engineer@Udacity Graduate https://wolfapple.github.io