Local Variable Scope in Ruby

How local variables interact with method invocations, blocks, and method definitions.

What types of variables does Ruby have?

Ruby has several types of variables, all defined by where they are accessible within your code.

  • Global Variables: “$global” ← (How the variable is declared.)
$variable = “I am available throughout your entire app”
  • Class Variables: “@@class” ← (How the variable is declared.)
@@class_variable = “I am accessible by instances of your class, as well as the class itself.”
  • Instance Variables: “@instance”← (How the variable is declared.
@instance_variable = “I am available throughout the current instance of this class.”
  • Constant Variable: “CONSTANT” ← (How the variable is declared.)
MY_CONSTANT = “Available throughout your app”
  • Local Variables: “local” ← (How the variable is declared.)
local_variable = “I must be passed around to cross scope boundaries, otherwise I obey all scope boundaries.”
  • Block Variables (a type of local variable): “|var1, var2|” ← (How the variable is declared.)
    Block variables are always scoped local to the block. This means scope is determined by the block so anything in between the “do..end” for multiline blocks, or the “{..}” (Curly Braces) for single line blocks.
  • * Block variables are also considered a form of local variables.*
def random_method do |var1,var2|  #inner scope starts after "do"
p ...
end # inner scope closed
# block scope is inaccessible here - var1 and var2 are not accessible and will generate an error if you try to access them.

What is variable scope?

The scope of you variable is where in your program the variable is available for use. Where you create or initialize the variable determines where it will be accessible (the variable’s scope) by the program.

Inner scope can access variables initialized in an outer scope, but not vice versa.

The creation of new scope by the block only happens when the do/end or {..} is following a method invocation. Without a method invocation the do/end or {..} is not considered a block and therefore does not create a new inner scope for variables.

What is a local variable?

In the code snippet below, we can see the second method (animal_noises) try to access a local variable declared in the first method (name_cat). Because “name” is local to name_cat, animal_noises cannot access “name” because it no longer exists.

How local variables interact with method definitions:

On line 7: # Here (verbiage) acts as a variable which in a method, we call an argument or parameter.

The (verbiage = “hi”) bit sets a default parameter. This is useful if you need a default value printed.

In this case we could simply print line 13 from above, without any custom parameter and it would default to printing “hi”. Line 12 prints our custom argument “goodbye” while line 13 prints our default value because we haven’t added a custom argument/parameter.

Line 12: greetings("goodbye")  # => "goodbye"
Line 13: greetings() # => "hi"

Alternatively, you can invoke greetings on line 13 without parenthesis:

Line 13: greetings   # => "hi" 

Generally, the latter syntax without parenthesis is convention in Ruby, when not passing in custom arguments. Having set a default parameter as (verbiage = “hi”) even if we pass no parameter

Variables as Pointers:

a = 17 
a.object_id => 42
puts a => 17
b = a
b.object_id => 42
puts b => 17

In the above case, the number 17 is the object, “a” and “b” are just variables pointing to the same object, and that is why they share the same object id.

Why does this matter? If you unintentionally reassign variables you can find your program behaving in unexpected ways. Consider the following:

a = 25
b = a
puts a => 25
puts a.object_id => 45
puts b => 25
puts b.object_id => 45
a = "hello"
puts a => "hello"
puts a.object_id => 36
puts b => 25
puts b.object_id => 45

In the above we reassign “a” as a string “hello”. When we print a we get that updated string object, including a new object id. The variable “b” is however still pointing at the original integer object.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store