Picture of stu

Use class instance variables, not class variables

  • Posted By Stuart Halloway on November 16, 2006

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?

Comments
  1. zdennisNovember 16, 2006 @ 04:18 PM
    I agree with you completely and I explain my reasons http://www.continuousthinking.com/2006/11/17/ruby-class-variable-or-class-instance-variables Ola Bini I think is off base with his thinking. Alot of times class variables are accessed directly, and debugging open variables like that that aren't protected via encapsulation are a pain to track down, in any language.
  2. Tim LucasNovember 19, 2006 @ 07:02 PM
    I was surprised to see no mention of Rails' class_inheritable_reader/writer and friends...
  3. Ola BiniJanuary 23, 2007 @ 10:09 AM
    Hi, I would have to agree with zdennis and you about me being off base regarding this issue. Basically, my big problem isn't with class instance variables as such (au contraire), but with mixing class variables and class instance variables. In most cases I now try to avoid using class variables at all. Regards
  4. GregJanuary 25, 2007 @ 04:20 PM
    I also posted on this: http://www.oreillynet.com/ruby/blog/2007/01/nubygems_dont_use_class_variab_1.html