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.