I recently fell into this class variable trap described in the posts above. Here is some code simulating my problem.
class Person @@count = 0 def initialize(name) @name = name @@count += 1 end end class Customer < Person @@count = 0 def self.count puts @@count end end a = Person.new("Jim Bob") b = Person.new("Jason Yates") c = Customer.new("Albert Einstein") puts Customer.count
3
You would expect to get '1' back from the 'Customer.count' method. It is the more obvious behavior or the one with the least surprise. The issue is, as you may have already noticed, class variables are shared with its subclasses. This behavior, speaking from personal experience here, can lead to very confusing and hard to diagnose bugs.
The problem above is easily solved by the use of class instance variables.
class Person class << self; attr_accessor :count; end def initialize(name) @name = name self.class.count ||= 0 self.class.count += 1 end end class Customer < Person end a = Person.new("Jim Bob") b = Person.new("Jason Yates") c = Customer.new("Albert Einstein") puts Customer.count
1
As you can see this simulates the expected behavior.
This will all become mute fairly soon anyways. In Ruby 1.9, class variables are now read-only by its subclasses. With this even the first example should work correctly.