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