Ruby Variable Scope: Class Variables vs. Instance Variables

When working with Ruby, understanding the scope of different types of variables is crucial for writing effective and bug-free code. Two common types of variables you’ll encounter are class variables (@@name) and instance variables (@name). While they might seem similar at first glance, they have distinct behaviors and use cases. This blog post will explain the differences between these variables, their scopes, and when to use each type.

Class Variables (@@name)

Class variables in Ruby are shared among a class and all of its subclasses. They are denoted by a double @ symbol (@@). Because they are shared, changes to a class variable in one instance of the class will affect all instances of the class.

Characteristics of Class Variables:

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class User
  @@count = 0
  
  def initialize(name)
    @name = name
    @@count += 1
  end

  def self.count
    @@count
  end
end

class Admin < User
end

user1 = User.new("Alice")
user2 = User.new("Bob")
admin1 = Admin.new("Charlie")

puts User.count   # Output: 3
puts Admin.count  # Output: 3

In this example, the @@count variable is shared among the User class and its subclass Admin. Each time a new User or Admin instance is created, @@count is incremented. Thus, User.count and Admin.count return the same value.

Instance Variables (@name)

Instance variables, denoted by a single @ symbol (@), are tied to a specific instance of a class. Each object has its own set of instance variables, which are not shared with other instances or the class itself.

Characteristics of Instance Variables:

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class User
  def initialize(name)
    @name = name
  end

  def name
    @name
  end
end

user1 = User.new("Alice")
user2 = User.new("Bob")

puts user1.name  # Output: Alice
puts user2.name  # Output: Bob

In this example, @name is an instance variable. Each User object has its own @name variable. Changing @name in user1 does not affect user2, and vice versa.

Key Differences

Scope:

Class Variables (@@): Shared across the entire class and its subclasses.

Instance Variables (@): Specific to each instance of a class.

Usage:

Class Variables: Use when you need to store information that should be consistent across all instances of a class and its subclasses, such as configuration settings or counters.

Instance Variables: Use for storing information specific to an instance, such as attributes of an object.

Visibility:

Class Variables: Can be accessed and modified by class methods, instance methods, and subclasses.

Instance Variables: Only accessible within the instance they belong to.

Class variables are shared among all instances and subclasses, making them suitable for data that needs to be consistent across a class hierarchy. Instance variables, on the other hand, are unique to each object, making them ideal for storing instance-specific data.