What is the difference between a class instance variable and a class variable in Ruby?

What is the difference between a class instance variable and a class variable in Ruby?

I understand that class variables (@@var) are shared across all instances of a class, while instance variables (@var) belong to a single object. However, where do class instance variables fit in, given that we already have class variables?

Could someone clarify their differences and when to use each?

Here’s an example:

class S
  @@k = 23
  @s = 15
  
  def self.s
    @s
  end
  
  def self.k
    @@k
  end
end

p S.s # 15  
p S.k # 23  

I also realized that Ruby class variables (@@var) are inherited, while class instance variables (@var) are not. Could someone explain the best use cases for both?

Basic Explanation of Class Variables @@var :

The key difference is that class variables (@@var) are shared among the class and all of its subclasses. This means that modifying a class variable in a subclass affects all instances of the parent class as well.

For example:
class Parent
  @@shared_var = 10
end

class Child < Parent
  @@shared_var = 20
end

p Parent.class_variable_get(:@@shared_var) # => 20
p Child.class_variable_get(:@@shared_var)  # => 20

Here, changing @@shared_var in Child also affects Parent, which may lead to unintended consequences."

Introducing Class Instance Variables @var : However, class instance variables (@var) behave differently—they belong to the class itself, not to instances of the class, and they are not shared with subclasses.

Here’s an example using class instance variables:

class Parent
  @not_shared = 10

  def self.not_shared
    @not_shared
  end
end

class Child < Parent
  @not_shared = 20
end

p Parent.not_shared # => 10
p Child.not_shared  # => 20

Unlike @@var, @var is independent in each class. Each class has its own version of @not_shared, making it safer for maintaining encapsulated state."

To summarize:

Use @var (class instance variables) when you want class-specific state that is not inherited by subclasses. This is useful for per-class configuration settings or internal state management.

For example, ActiveRecord models often use class instance variables for configuration:

class Model
  @config = {}

  def self.config
    @config
  end
end

class User < Model
  @config = { table_name: "users" }
end

p Model.config # => {}
p User.config  # => {:table_name=>"users"}

This ensures that Model and User each maintain independent configurations rather than sharing the same mutable @@var state."