Nope, don’t do it!

Look at this and see how class variables are being treated:

# ruby code

class A
  def method_a
    @@var = 1
  end
end

class B < A
  def method_b
    @@var = 2
  end
end

a = A.new
a.method_a #=> 1
A.class_variable_get("@@var") #=> 1

b = B.new
b.method_b #=> 2
B.class_variable_get("@@var") #=> 2

And now, this little gem:

# ruby code

A.class_variable_get("@@var") #=> 2 o.O

Let’s go about it the other way around:

# ruby code

b = B.new
b.method_b #=> 2
B.class_variable_get("@@var") #=> 2

a = A.new
a.method_a #=> 1
A.class_variable_get("@@var") #=> 1

B.class_variable_get("@@var") #=> 1 o.O

Clearly, inheritence and class variables aren’t the best of friends in Ruby.

So how do you get around this?

It depends on what you’re trying to accomplish. If you want a “globally” accessible constant value, what you should be using is a constant.

# ruby code

class A
  VAR = 1
end

class B < A
  VAR = 2
end

A::VAR #=> 1
B::VAR #=> 2

A::VAR #=> 1

And what if your value isn’t constant? Class-level instance variables to the rescue:

# ruby code

class A
  class << self
    def method_a
      @var = 1
    end
  end
end

class B < A
  class << self
    def method_b
      @var = 2
    end
  end
end

A.method_a #=> 1
A.instance_variable_get("@var") #=> 1

B.method_b #=> 2
B.instance_variable_get("@var") #=> 2

A.instance_variable_get("@var") #=> 1

Plus a little something for convenience:

# ruby code

class A
  class << self
    attr_reader :var

    def method_a
      @var = 1
    end
  end
end

A.method_a #=> 1
A.var #=> 1

And now you know. :neckbeard: