A Ruby object is:
- Data - A map of instance variable and the values associated. Note that instance variables are private to the instance itself.
- Behavior - A pointer to a class where the methods this instance responds to are defined. Note methods may be inherited from parent class.
Class is an object in Ruby. By writing:
class Foo
@bar = 8
def self.get_bar
@bar
end
end
You get the following data model (not exactly, the hierarchy of Foo's ancestors and their eigen classes have been removed):
Class
|
Foo class ptr [eigenclass of Foo]
@bar = 8 ---------> method - get_bar
The instance variable at class scope defines the private data for that class object. From the model above, this instance variable is accessible through instance methods defined in the eigenclass of Foo, and in its ancestor chain Class, Module, Object, Kernel, BasicObject. These instance variables defined some data associated with the class object Foo.
By writing:
class FooChild < Foo
end
You have
Class
|
Foo class ptr [eigenclass of Foo]
@bar = 8 ---------> method - get_bar
| |
FooChild class ptr [eigenclass of FooChild]
<Nothing> ---------> <Nothing>
Class object FooChild inherits the method get_bar from the eigen class of Foo, so you can call FooChild.get_bar. However, since the receiver is FooChild, and no instance variable @bar is associated with FooChild, the default value nil will be returned.
The above analysis is more detailed in the book Meta-programming Ruby.
Class variable (@@bar2), IMO is a scoped variable with strange resolving order. By refering @@bar2 in Foo's class scope, it will lookup in the ancestor chain of Foo for the definition of @@bar2, FROM TOP TO BOTTOM. So it will first lookup in BasicObject, then Kernel, then Object, and finally Foo.
Have a play with the following example:
class Foo
@@bar = 1
def self.show
puts @@bar
end
end
Foo.show #=> 1
class Object
@@bar = "hahaha"
end
Foo.show #=> hahaha
class_attribute(a method defined by ActiveSupport) is preferred.class_attributewas created because class variables are shared between superclasses and subclasses, thus modifications on their values inside subclasses are applied on superclasses too, which rarely is desired. Usingclass_attributethis effect is prevented