Curious Effects of Different Ruby Class & Module Nesting Styles

Typically, in Ruby, we see modules and classes nested by having one declaration inside of the the other.

When the outer class or module has previously been declared, however, we can also declare the nested one directly using its fully qualified name, and it is not uncommon to see that done.

On the surface, these seem to be 2 ways to do exactly the same thing, and for the most part they are. They are not doing exactly the same thing, however, and that can result in some interesting side effects. We start to see those effects when methods methods defined within our declarations make reference to constants.

As you can see, each of the instance methods of Foo::Bar  is accessing constants from a different level of nesting.

What’s going on is that the nesting with respect to an executing method belongs to the method itself and not the class or module on which it is defined. The source of that nesting is nesting of class  and module  code blocks at the point where the method was defined.

The side effects of this can get positively weird.

Say what? The hello  instance method cannot even reference its own class using an unqualified name? That is because the Bar  constant belongs to the Foo  module, but since the method was not defined within a module Foo  block, its constants (including Bar ) are not implicitly available.