Class variables are variables shared across all instances of a class. They're accessible from instance methods, class methods and (with accessors) from outside the class itself. They're not often used, but in some techniques and patterns (such as the singleton pattern), they're essential.
A class variable is denoted by two at signs prepended to a variable name, not to be confused with instance variables which have only one at sign prepended. For example, @age is an instance variable, while @@family is a class variable. Similar to instance variables, class variables may only appear in instance and class methods, as well as the class declaration itself.
Note that you can use class variables outside of class or instance methods, but still inside of the class itself. This is not a place you typically see Ruby code, but it's perfectly valid. This code is executed when the class is defined, typically at program startup or when the containing file is required or loaded. Any Ruby code can go there, there aren't really any restrictions. In fact, many things that seem like language features (like attr_reader type "features") are really method calls that dynamically define new class methods. But any class variables that need to be set can be set here, or from within any class or instance methods.
This example program demonstrates that any code at all can be put inside a class declaration. The Inside of TestClass message will be printed before anything else, since that code is run when the class is defined. It isn't until after that the class method is called and the Hello from class method message will be printed.
#!/usr/bin/env ruby class TestClass puts "Inside of TestClass" def self.say_hello puts "Hello from class method" end end TestClass.say_hello
For every class lineage, there is only one set of class variables. If @@wheels is set in the Motorcycle class, then is set again in the MotorcycleWithSidecar class (which is inherited from Motorcycle), then even in the Motorcycle class, @@wheels will be 4, as set in MotorcycleWithSidecar.
However, this is only true for variables already set in the parent class. If a child class then sets a second variable, that variable doesn't get set in the parent class. So if MotorcycleWithSidecar then sets @@num_passengers, that variable won't be set in the Motorcycle class.
You can visualize this as inherited access. When a class variable is set, Ruby first checks to see if the parent class has defined this variable, or if any superclass up the inheritance tree has defined the variable. If so, that variable is set, affecting the entire inheritance tree. If not, only the class that defined the new variable will set the variable. Parent classes will not have the variable set at all. In other words, class variable lookups go up the inheritance tree, and never downward.
The following example code demonstrates this. Also, note the second section. Even though the B class never uses the variable, the variable set in C still affects A.
#!/usr/bin/env ruby class Motorcycle @@wheels = 2 def self.wheels @@wheels end end class MotorcycleWithSidecar < Motorcycle @@wheels = 4 # Only MotorcycleWithSidecar can access @@test @@test = 10 end class A @@test = 1 def self.test; @@test; end end class B < A end class C < B @@test = 2 end puts A.test puts Motorcycle.wheels
Class Instance Variables
Perhaps confusingly, Ruby also has the concept of a class instance variable. These are instance variables (which begin with one at sign, like @this) that appear within the class definition, but outside of any methods. These instance variables belong to that particular class, and to no other classes within the class hierarchy.
Where do these class instance variables come from? For every class, there is an instance of the Class class that defines the class. For instance, the String constant (yes, class names are just constants) refers to an instance of the Class class. This object defines what String objects are like, what methods they have and so forth. These class objects are just like any other objects, and they can have their own instance variables.
This can be seen as a fluke, an artifact of how Ruby implements classes. However, they do have the added benefit of not interacting in any way with the other classes in the hierarchy. So, in a way, using class instance variables can have distinct advantages over using simple class variables. The only disadvantage is accessing those instance variables from outside the class declaration, it requires a bit of (confusing to some) extra syntax.
In order to get at class instance variables from outside of the class declaration, you need to create an instance method of the class itself. In other words, we must access the singleton class for the class object we're creating by defining the class. This can be tough to wrap your mind around but if all else fails, you can simply follow the pattern in the example below.
The following defines a small hierarchy of singleton variables. So the child singleton doesn't interfere with the parent singleton, class instance variables are used instead of class variables. Had class variables been used, and Square set a shared @@instance class variable, any future calls to Shape::get_instance would have returned a Square object, not the intended Shape object.
#!/usr/bin/env ruby module GetInstance def get_instance if instance == nil instance = new else instance end end end class Shape @instance = nil class << self attr_accessor :instance end extend GetInstance end class Square @instance = nil class << self attr_accessor :instance end extend GetInstance end shape = Shape.get_instance square = Square.get_instance puts shape.inspect puts square.inspect