Programming
Juan Pablo Balarini • 25 APR 2023
Developing with Ruby: Types of Variables
At the heart of Ruby programming, we find variables. Variables in Ruby are memory locations that hold temporary data that can be potentially needed ahead by any program.
To put it simply: a variable is just a label. With them, we give names to things in Ruby programs. They can sound plain and obvious, but actually, they are pretty useful. In a world without variables, you would have to repeat every action every time you want to refer to it. That’s why variables are so important.
How to create and use a variable in Ruby
Creating a variable in Ruby is as easy as performing a “variable assignment”, which means associating a Ruby object with a variable name. To use a variable, you just need to declare it (a.k.a. write its name)
favorite_language = 'ruby'
Types of Ruby variables
There are different types of variables in Ruby. Each variable has its own way of being declared by adding a special character at the beginning of the name. In the following table, you’ll find 4 types of Ruby variables and their respective associated symbols.
Variables are distinguished from one another thanks to their scope. Variable scope refers to what variables are available (to your program) at any given point in time. Let’s dive into each category to understand each type of variable better.
Local variables
Local variables have the most narrow scope among Ruby variables. They are defined inside the code construct in which they are declared, and once the method returns, they no longer exist. In a nutshell: a local variable is only accessible within the limits of the block of its declaration. An important note: local variables don’t need to be initialized. As we’ve seen in the table above, you can name them starting with a lowercase letter from a to z, or with an underscore (_).
language = 'ruby';
_language = 'ruby';
Instance variables
Instance variables have a wider scope. They are available across methods with a local value for a specific instance. Due to their nature, they are used to share data inside a Ruby object but they can change from object to object. Establishing simple parallelism, each object has its own set of instance variables as every person has their own name, age, nationality, etc.
An instance variable’s name starts with a @ sign. You don’t need to initialize an instance variable. Uninitialized instance variables have the nil value.
class Car
def initialize(make, model)
# Instance variables
@car_make = make
@car_model = model
end
def print_car
puts "Car is: #{@car_make} #{@car_model}"
end
end
# Create Cars
car1 = Car.new("BMW", "323")
car2 = Car.new("Mini", "Cooper")
# Display car information
car1.print_car
car2.print_car
Output:
Car is: BMW 323
Car is: Mini Cooper
Class variables
Class variables need to be initialized before they can be used in method definitions (otherwise, it will result in an error). They belong to a whole class, which makes them accessible from anywhere inside that specific class. Class variables are available across different objects shared by all the descendants of that class. If their value is changed in one instance, it will change at every instance. This type of variable begins with @@.
class Car
@@car_amount = 0
def initialize(make, model)
# Instance variables
@car_make = make
@car_model = model
end
def print_car
puts "Car is: #{@car_make} #{@car_model}"
end
def self.increase_amount
@@car_amount += 1
end
def self.print_total_cars
puts "Number of cars is: #{@@car_amount}"
end
end
# Create Cars
car1 = Car.new("BMW", "323")
Car.increase_amount
car2 = Car.new("Mini", "Cooper")
Car.increase_amount
# Display car information
car1.print_car
car2.print_car
Car.print_total_cars
Output:
Car is: BMW 323
Car is: Mini Cooper
Number of cars is: 2
Global variables
Global variables have the widest scope among Ruby variables. They can be accessed from anywhere in the program and are available across different classes. A global variable assignment impacts the global status. By default, an uninitialized global variable has a nil value. Using global variables is not recommended because they make programs complex and cryptic. They begin with a $ symbol.
$global_vehicle_amount = 0
class Car
def initialize(make, model)
@car_make = make
@car_model = model
end
def self.increase_amount
$global_vehicle_amount += 1
end
def self.print_vehicle_amount
puts "Number of vehicles (from Car) is: #{$global_vehicle_amount}"
end
end
class Motorcycle
def initialize(make, model)
@motorcycle_make = make
@motorcycle = model
end
def self.increase_amount
$global_vehicle_amount += 1
end
def self.print_vehicle_amount
puts "Number of vehicles (from Motorcycle) is: #{$global_vehicle_amount}"
end
end
# Create Vehicles
car1 = Car.new("BMW", "323")
Car.increase_amount
car2 = Car.new("Mini", "Cooper")
Car.increase_amount
motorcycle = Motorcycle.new("Husqvarna", "401")
Motorcycle.increase_amount
Car.print_vehicle_amount
Motorcycle.print_vehicle_amount
puts "Going to reset global amount"
$global_vehicle_amount = 0
Car.print_vehicle_amount
Motorcycle.print_vehicle_amount
Output:
Number of vehicles (from Car) is: 3
Number of vehicles (from Motorcycle) is: 3
Going to reset global amount
Number of vehicles (from Car) is: 0
Number of vehicles (from Motorcycle) is: 0
The “Fifth Ruby Variable”: Constants
A constant in Ruby is like a variable except for the fact that its value remains constant as long as the program keeps running. It is used for things that you don’t expect to change. Its scope depends on whether it is defined within or outside a class or module. In the first case, it can be accessed from within. But, if it’s defined outside, its availability is global. Their names begin with an uppercase letter. In this sense, constants look like local variables with capital letters, but they have the visibility of global values.
HELLO_MESSAGE = 'Hi!'
class Car
NUMBER_OF_WHEELS = 4
def initialize(make, model)
@car_make = make
@car_model = model
end
def print_car
puts "#{HELLO_MESSAGE} Car is: #{@car_make} #{@car_model}. Has #{NUMBER_OF_WHEELS} wheels"
end
end
# Create Cars
car1 = Car.new("BMW", "323")
car2 = Car.new("Mini", "Cooper")
# Display car information
car1.print_car
car2.print_car
puts HELLO_MESSAGE
puts NUMBER_OF_WHEELS
Output:
Hi! Car is: BMW 323. Has 4 wheels
Hi! Car is: Mini Cooper. Has 4 wheels
Hi!
uninitialized constant NUMBER_OF_WHEELS (NameError)
IMPORTANT:
If you reference an uninitialized constant, it will produce an error. If you make an assignment to a constant that is already initialized, it produces a warning.
Ruby Pseudo-Variables
In addition to the variables we mentioned before, there are also a few pseudo-variables. What is their main characteristic? They look like local variables but they behave like constants. It’s not possible to assign a value to pseudo-variables as their value is predetermined. Here’s a list of them:
- self − The receiver object of the current method.
- super - Also refers to the receiver object of the current method but, when you send a message to super, the method look-up changes and starts from the super-class of the class containing the method that uses super.
(The two pseudo-variables above vary dynamically as the code executes).
- true − Value representing true.
- false − Value representing false.
- nil − Value representing undefined.
- __FILE__ − The name of the current source file.
- __LINE__ − The current line number in the source file.
Final notes
To master the use of variables in Ruby, you need to practice. We encourage you to exercise the use of different variables, there’s no doubt you’ll get there with persistence and focus. Any questions or need for Ruby's development mastery? Give us a shout!