1. Computing

Class Variables

By

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

Inherited Access

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
  1. About.com
  2. Computing
  3. Ruby
  4. Beginning Ruby
  5. Variables
  6. Class Variables

©2014 About.com. All rights reserved.