This content has been automatically translated from Ukrainian.
In Ruby, there are several types of variables that differ by who they belong to - an object, a class, or all descendants at once. Let's break it down simply with examples.
@ - instance variable
This is a regular variable that belongs to a specific object. Each instance of the class (object) has its own copy of such a variable.
class User
def initialize(name)
@name = name
end
def name
@name
end
end
u1 = User.new("Oleh")
u2 = User.new("Ira")
u1.name # => "Oleh"
u2.name # => "Ira"
Each user has their own name. @name is not shared between objects - it is their personal data.
@@ - class variable
A variable with two at signs (@@) is shared among all instances and subclasses. It lives within the entire class hierarchy.
class Animal
@@count = 0
def initialize
@@count += 1
end
def self.count
@@count
end
end
class Dog < Animal; end
a1 = Animal.new
d1 = Dog.new
Animal.count # => 2
Dog.count # => 2
Both Animal and Dog see the same @@count variable. If a subclass changes it, it affects the parent class. Because of this, @@ is considered a dangerous and outdated practice - it's better to avoid using it.
Class instance variable - a safe alternative to @@
You can create a variable at the class level, but so that it belongs only to that class, not to its descendants. This is a regular @variable, but declared at the level of the class itself (not inside initialize).
class User
@count = 0
def self.add_user
@count += 1
end
def self.count
@count
end
end
class Admin < User; end
User.add_user
User.count # => 1
Admin.count # => nil
In this example, User has its own @count, and Admin has a separate one (initially nil until defined). This makes the code safe and predictable.
Like it?React
🧵
This post doesn't have any additions from the author yet.