Use class instance variables, not class variables

At the Rails Edge this morning, PragDave spoke out against class variables, and in favor of class instance variables. I totally agree. Look at this code:

  # why I don't like @@attributes
  class Base
    @@shared = 'cattr from base'
    class << self
      attr_accessor :unshared
    end
    def self.shared
      @@shared
    end
    self.unshared = 'attr from base'
  end
  class Derived < Base
    @@shared = 'cattr from derived'
    self.unshared = 'attr from derived'
  end
  class Ouch
    class << self
      attr_accessor :unshared
    end
    def self.shared
      @@shared
    end
  end
  puts Base.unshared
  puts Base.shared
  puts Derived.unshared
  puts Derived.shared
  puts Ouch.unshared
  puts Ouch.shared

Can you guess what this program will do? It demonstrates three of the ways that class variables cause trouble:

  1. The behave differently from instance variables if they are missing.
  2. They are shared across an inheritance hierarchy in a counterintuitive way.
  3. They require a new syntax, when the instance variable syntax is perfect for the task.

But maybe I am wrong. Ola Bini, who says many wise things, appears to be arguing exactly the opposite. Does anybody have a use case where class variables are the best solution?

Get In Touch