Is It Bad to Use Class Variables in Ruby?

Class variables can be problematic when it comes to inheritance because each subclass inherits the same class variable from its superclass (i.e. it does not get a new copy of a class variable). This can lead to confusion as they might (accidentally) be reassigned by any of the class's subclasses, affecting all other classes that inherit the same class variable. Consider, for example, the following:

class Parent
  @@counter = 0

  def initialize
    @@counter += 1
  end

  def self.counter
    @@counter
  end
end

class Child < Parent
  @@counter = 100
end

a = Parent.new
b = Parent.new
c = Parent.new

d = Child.new

puts Parent.counter # output: 104

The output here is 104 because the Child class sets the initial value of @@counter to 100. After that there are a total of four object instances that are created. This results in @@counter being incremented four times, updating the @@counter value to 104. If that sounds confusing, then perhaps the following example will give you a clearer understanding of this:

class Parent
  @@name = "parent"

  def self.name
    @@name
  end
end

puts Parent.name # output: "parent"

class Child < Parent
  @@name = "child"
end

puts Parent.name # output: "child"

Similarly, when/if an ancestor class changes the value of the class variable, you would run into the same issue:

class Parent
  @@name = "parent"

  def self.name
    @@name
  end
end

puts Parent.name # output: "parent"

class Object
  @@name = "object"
end

puts Parent.name # output: "object"

As you can see, any subclass or ancestor class, that is defined after the parent, could potentially reassign a class variable leading to unexpected behavior:

class Parent
  @@name = "parent"

  def self.name
    @@name
  end
end

puts Parent.name # output: "parent"

class Child < Parent
  @@name = "child"
end

puts Parent.name # output: "child"

class Object
  @@name = "object"
end

puts Parent.name # output: "object"

Therefore, you should generally avoid class variables, and try to use instance variables instead wherever possible.


This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.