Table of contentsClick link to navigate to the desired location
This content has been automatically translated from Ukrainian.
There are several types of variables in Ruby that differ in that, who owns them - to an object, a class, or all descendants at once. Let's deal with examples simply.
@ - instance variable
This is a normal variable that belongs to a specific object. Everybody 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 does not share between objects - that's their personal data.
@@ - class variable
Variable with two dogs (@@) common between all instances and subclasses. It lives inside 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 variable @@count. If a subclass changes it, it affects the parent class. Because of this, @@ is considered a dangerous and outdated practice - it is better to avoid its use.
Class instance variable - a safe alternative to @@
You can create a variable at class level, but that it should belong only to this class, not to the heirs. This is a normal @variable, but declared at the level of the class itself (and 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 (nil first until it is defined). This makes the code safe and predictable.
This post doesn't have any additions from the author yet.