All original content is created in Ukrainian. Not all content has been translated yet. Some posts may only be available in Ukrainian.Learn more

[Ruby] What is the difference between variables that start with @, @@, and $?

Post cover: [Ruby] What is the difference between variables that start with @, @@, and $?
Table of contentsClick link to navigate to the desired location
This content has been automatically translated from Ukrainian.
In Ruby, variables that start with @, @@, and $, have different levels of visibility and usage (scope). Let's look at examples and try to explain the differences as simply as possible.

@ or @instance_variable

Variables that start with @ are instance variables. They belong to a specific object (instance of a class) and are accessible only within that object. Each instance of a class has its own instance variables. Let's check:
class Example
  def initialize(value)
    @instance_variable = value
  end

  def show
    @instance_variable
  end
end

obj1 = Example.new(10)
obj2 = Example.new(20)

puts obj1.show  # Will output 10
puts obj2.show  # Will output 20
The object's initialization method takes a value and sets it in the instance variable (when we call the show method on the obj1 object, the initialization is executed first and then the method itself). The show method returns the value of the instance variable.
That is, a variable defined with the @ symbol allows sharing values among the class methods in the context of the object. Each new object, for example, obj2 will have its own value in the @instance_variable.

@@ or @@class_variable

Variables that start with @@ are class variables. They are shared among all instances of the class. If one of the class variables is changed in one instance of the class, that change will be visible in all other instances of that class.
A simple example:
class Example
  @@class_variable = 0

  def self.increment
    @@class_variable += 1
  end

  def self.show
    @@class_variable
  end
end

Example.increment
Example.increment

puts Example.show  # Will output 2
That is, class variables affect all objects of that class. Sometimes this can be quite dangerous, and one must be very careful not to cause harm by affecting all objects.

$ or $global_variable

Variables that start with $, are global variables. They are accessible from any part of the program, regardless of the scope. Using global variables can complicate tracking the state of the program, so they should be avoided if possible.
An example:
$global_variable = 10

def show_global
  $global_variable
end

puts show_global  # Will output 10
This example is not very illustrative, but technically - this global variable can be changed and used anywhere in the program.

In summary

  • @instance_variable: instance variable, unique to each object.
  • @@class_variable: class variable, shared among all instances of the class.
  • $global_variable: global variable, accessible from any part of the program.
And let's learn to write tests - you can always check some assertions using tests.
test.rb
require 'rspec'

class Example
  @@class_variable = 0
  $global_variable = 0

  def initialize(value)
    @instance_variable = value
  end

  def increment_class_variable
    @@class_variable += 1
  end

  def increment_global_variable
    $global_variable += 1
  end

  def instance_variable
    @instance_variable
  end

  def self.class_variable
    @@class_variable
  end

  def self.global_variable
    $global_variable
  end
end

RSpec.describe 'Different types of variables' do
  before do
    @example1 = Example.new(1)
    @example2 = Example.new(2)
  end

  context 'instance variables' do
    it 'are unique to each object' do
      expect(@example1.instance_variable).to eq(1)
      expect(@example2.instance_variable).to eq(2)
    end
  end

  context 'class variables' do
    it 'are shared among all instances of the class' do
      @example1.increment_class_variable
      @example2.increment_class_variable
      expect(Example.class_variable).to eq(2)
    end
  end

  context 'global variables' do
    it 'are accessible from any part of the program' do
      @example1.increment_global_variable
      @example2.increment_global_variable
      expect(Example.global_variable).to eq(2)
    end
  end
end
rspec test.rb ...
Finished in 0.01932 seconds (files took 0.28601 seconds to load)
3 examples, 0 failures

This post doesn't have any additions from the author yet.

Why is an empty string in Ruby not false?
31 May 14:39

Why is an empty string in Ruby not false?

meme code
meme code@memecode
The scope of a local variable in Ruby
03 Jun 16:46

The scope of a local variable in Ruby

meme code
meme code@memecode
What is the difference between int and bigint in Ruby? Minimum and maximum values.
13 Jun 06:37

What is the difference between int and bigint in Ruby? Minimum and maximum values.

meme code
meme code@memecode
What does the error 'is out of range' mean in Ruby on Rails? Range Error - Integer with a limit of 4 bytes
13 Jun 07:18

What does the error 'is out of range' mean in Ruby on Rails? Range Error - Integer with a limit of 4 bytes

meme code
meme code@memecode
What is immutability and mutability?
19 Jun 07:48

What is immutability and mutability?

meme code
meme code@memecode
What will be the result of adding 10.5 and 10?
23 Jun 13:23

What will be the result of adding 10.5 and 10?

meme code
meme code@memecode
What is a function in programming?
24 Jun 18:15

What is a function in programming?

meme code
meme code@memecode
[Fix] extconf.rb failed during the installation of the Ruby library Gosu
27 Jun 16:38

[Fix] extconf.rb failed during the installation of the Ruby library Gosu

meme code
meme code@memecode
How to make an empty git commit?
28 Jun 08:33

How to make an empty git commit?

meme code
meme code@memecode
Ruby library Gosu for creating 2D games
29 Jun 08:48

Ruby library Gosu for creating 2D games

meme code
meme code@memecode
Gosu Ruby Tutorial - пройдемось по офіційній документації
03 Jul 11:50

Gosu Ruby Tutorial - пройдемось по офіційній документації

meme code
meme code@memecode
We are writing a demo game Drones vs Zombies (Gosu / Ruby)
12 Jul 12:17

We are writing a demo game Drones vs Zombies (Gosu / Ruby)

meme code
meme code@memecode