Ruby classes are represented by a
RClass structure. It’s a fairly big structure, so I’ve broken it down according to what a Ruby class actually does and what it contains.
A Ruby class is a Ruby object that also contains method definitions, attribute names, a superclass pointer, and a constants table.
- Pat Shaughnessy
class Fruit attr_accessor :colour attr_accessor :taste end
A Ruby class contains method definitions.
Method definitions are stored in a
m_tbl method table. In Fruit, this will be a table that contains the keys
taste=, and whose values are pointers to the actual method definitions and their YARV instructions.
A Ruby class contains instance-level attribute names.
As mentioned in the previous post, a
RObject contains a pointer
iv_index_tbl which is a hash table that maps attribute names to their positions in the
ivtpr array. In Fruit, this will be a hash table that contains the keys
taste, and whose values are their indices in the
A Ruby class is also a Ruby object.
p Fruit.class # Class p Fruit.singleton_class # #<Class:Fruit>
If you print out Fruit’s class, it shows Fruit as being an instance of the
Class class. A Ruby class is also a Ruby object.
As a Ruby object, a Ruby class will also have:
klassclass pointer that references the
RClassof its class (and is stored, like any other
RObject, in a
- Its own methods (called class methods - those that you define with
def self.some_method). These methods are not stored in the class itself, but in its metaclass, or sometimes called the singleton class. This singleton class is what
klassis set to, not Class.
- A table of its own class-level instance variables called
A Ruby class has a pointer to a superclass, which allows it implement inheritance.
class Pear < Fruit end p Pear.class # Class p Pear.superclass # Fruit
A Ruby class will have a
super pointer that references its superclass. In this case, Pear will have a
klass pointer referencing Class, and a
super pointer referencing Fruit. There is a dinstinction between the two -
klass refers to the class from which the Pear class object is instantiated, whereas
super refers to Pear’s logical superclass. The Pear class object is not instantiated from Fruit, but Class.
A Ruby class contains constants.
class Pear < Fruit SIZE = 6 # units in cm end
A Ruby class can contain constants. Constants are stored in a
const_tbl constants table.
Ruby classes are also objects. When a class is created, Ruby actually creates two objects - the class object itself, as well as a metaclass object.
In Ruby, there are class variables, which are dintinct from class-level instance variables, as mentioned above. Class-level instance variables are defined with a single
@ prepended to the variable name and are scoped to each individual class object. Class variables are defined with a double
@@ prepended to the variable name and is visible globally across all instances of the class. For example:
class Fruit @smell = nil @@edible = false def self.smell @smell end def self.edible @@edible end end class Pear < Fruit @smell = "Fragrant" @@edible = true end p Fruit.smell # nil p Pear.smell # "Fragrant" p Fruit.edible # true p Pear.edible # true
Internally, both types of variables are stored together in the same
iv_tbl tables of both Fruit and Pear. When setting a class-level instance variable,
@smell is set to
nil in Fruit’s
"Fragrant in Pear’s. However, when setting a class variable, Ruby checks the
iv_tbl of that class and all its superclasses for the presence of the variable, and sets them all to the same value. When Pear redefines
true, that change is also reflected in Fruit’s