Programming

Juan Pablo Balarini • 25 APR 2023

Developing with Ruby: Types of Variables

post cover picture

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.

 

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:

(The two pseudo-variables above vary dynamically as the code executes). 

 

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!

Stay updated!

project background