In Ruby, modules and classes are instances of the Module
and Class
classes, respectively. They get their names from the constant to which they are assigned. When you write:
class A::B
You effectively write:
A::B ||= Class.new do
This is the actual syntax for the account assignment syntax and assumes that the constant A
was correctly initialized and that it refers to Module
or Class
.
For example, consider how classes are usually defined:
class A
What really happens:
Object::A ||= Class.new do
Now when you write:
class A class B # ... end end
What actually happens looks like this:
(Object::A ||= Class.new).class_eval do (A::B ||= Class.new).class_eval do
Here what happens is in order:
- A new instance of
Class
assigned to the constant A
Object
, if it has not already been initialized. - A new instance of
Class
assigned to the constant B
A
, if it has not already been initialized.
This ensures that all outer classes exist before trying to define any inner classes.
There is also a scope change that allows you to access constants A
directly. For comparison:
class A MESSAGE = "I'm here!" end
According to this blog post, the main Ruby team calls the "current class" cref
. Unfortunately, the author does not specify, but, as he notes, it is separate from the context of self
.
As explained here , cref
is a linked list that represents the nesting of modules at some point in time.
The current cref
used to search for constant and class variables and for def
, undef
and alias
.
As others have argued, these are different ways of expressing the same thing.
There is, however, a subtle difference. When you write class A::B
, you assume that class A
already defined. If this is not the case, you will get a NameError
and B
will not be defined at all.
Writing correctly nested modules:
class A class B end end
Provides class A
before attempting to define B