Local Variables in Ruby

Pop Quiz: Consider the code below, and ask: where is the variable ‘greeting’ defined?

# locals.rb
if [true, false].sample
	greeting = "hello"
else
	greeting = 'Namaskaram'
end

puts greeting
# => hello world
# => Namaskaram


# to run: 
# ruby locals.rb

Why does the above code work? If you were using a language like c#, then you would have to write something like this:

# Imagine we are writing c# 
greeting = "" # the greeting will have to be defined outside the if statement

if [true, false].sample
	greeting = "hello"
else
 	greeting = 'Namaskaram'
end

puts greeting

This is a pain! Ruby gives us a long rope - we can hang ourselves with it if we’re not careful. But if we know what we are doing, this allows you to write elegant code.

The ruby code “works”, because methods are “called” on objects, and variables are stored somewhere - in objects. In this case, the variable is stored in the self object.

Pop Quiz: What is the self object here?

  • How would you edit the code in order to find the solution?
# locals.rb
if [true, false].sample
	greeting = "hello"
else
	greeting = 'Namaskaram'
end

puts "The self object is: #{self}"
puts greeting

# => The self object is: main
# => Namaskaram

If the self object is main then presumably, the local variable: greeting will be defined on it.

Pop Quiz: How can we determine if the local variable is defined on main?

puts "local variables on self: #{self.local_variables}"
# => local variables on self: [:greeting]

Answer: there is a method defined on Kernel which gives us the answer on a platter - the local_variables method. There also exists a very handy cousin method: instance_variables.

Written on November 23, 2023