What’s the difference between:
class A
class B
end
end
and
class A
end
class A::B
end
Update: These 2 approaches are not exactly the same.
In the second approach, B doesn’t have access to constants defined in A.
Also, as Matheus Moreira correctly stated, in the second approach, A must be defined before A::B can be defined.
What other differences are there?
In Ruby, modules and classes are instances of the
ModuleandClassclasses, respectively. They derive their names from the constant they are assigned to. When you write:You are effectively writing:
Which is valid constant assignment syntax, and assumes that the
Aconstant has been properly initialized and that it refers to aModuleor aClass.For example, consider how classes are usually defined:
What is effectively happening is this:
Now, when you write:
What actually happens looks like this:
Here’s what is happening, in order:
Classinstance is asssigned to theAconstant ofObject, unless it was already initialized.Classinstance is asssigned to theBconstant ofA, unless it was already initialized.This ensures the existence of all outer classes before attempting to define any inner classes.
There is also a change in scope, which allows you to directly access
A‘s constants. Compare:According to this blog post, the Ruby core team calls the “current class” the
cref. Unfortunately, the author does not elaborate, but as he notes, it is separate from the context ofself.As explained here, the
crefis a linked list that represents the nesting of modules at some point in time.As the others have stated, they are different ways of expressing the same thing.
There is, however, a subtle difference. When you write
class A::B, you assume that theAclass has already been defined. If it has not, you will get aNameErrorandBwill not be defined at all.Writing properly nested modules:
Ensures the
Aclass exists before attempting to defineB.