In Ruby, a class variable is a variable declared inside a class that's shared between the class and all its subclasses (i.e. each class instance has the same copy of a class variable). It is:
- Static — i.e. only a single copy of the variable exists, regardless of however many instances of the class you create;
- Created by adding a double at sign (
@@
) before a variable name (e.g.@@variable_name
); - Always private to outside access;
- Potentially problematic when it comes to inheritance.
For example, consider the following class where a static counter
is incremented each time a new object is instantiated:
class Entity
@@counter = 0
def initialize
@@counter += 1
end
def counter
@@counter
end
end
a = Entity.new
b = Entity.new
c = Entity.new
puts a.counter #=> 3
puts b.counter #=> 3
puts c.counter #=> 3
As you can see from the example above, all instances of the class return the same value from counter()
method, because @@counter
is a class variable that's shared across all instances of the Entity
class.
Consider another example, where a delimiter is declared as a class variable:
class Collection
@@delimiter = ", "
def self.from_str(str)
self.new(str.split(@@delimiter))
end
end
This can be inherited by other classes, where the same delimiter
would be used across all subclasses:
class Fruits < Collection
def initialize(fruits)
@fruits = fruits
end
attr_reader :fruits
end
a = Fruits.from_str('orange, apple, grapes')
b = Fruits.from_str('banana, mango')
print a.fruits #=> ["orange", "apple", "grapes"]
print b.fruits #=> ["banana", "mango"]
You should use class variables with caution as all subclasses inherit the same class variables from its superclass, which can lead to unexpected/confusing results.
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.