Short answer: Sometimes.
In an earlier post, I talked about how we define namespaced classes in Rails.
That is, should we use this form?
or this one?
As I was researching that post, I was trying to understand where the
namespaces were coming from when using the shorthand form of
MyModule::MyClass. There was no declaration of
MyModule as a
module or class in any of my code. I also know that, in plain Ruby, I
can’t define a class that way without first defining
If I try, I’ll get a
So how was my code loading into Rails without blowing up?
I searched Google with a query that matches the title of this post and didn’t find an answer, so I decided to research it and write the answer myself.
After discovering and using some handy tracing tips for the Rails autoloader, I was able to learn that Rails does indeed define modules in some cases.
MyModule is already defined as a class or namespace, the
autoloader never comes into play. But if it isn’t defined, the
autoloader tries to find and load a definition for me.
The Rails autoloader lives in
workhorse method is
load_missing_constant, which is called from a
const_missing handler that the autoloader injects into
load_missing_constant looks for a file that might define the
MyModule in this example). If it can’t find one,
autoload_module! to dynamically define
MyModule as a
module as long as
true if the potential module name
matches a directory name somewhere in one of my configured autoload
If there is no such directory, then the autoloader tries a few other
things. If none of them work, it will ultimately raise the same
NameError we get from stock Ruby.
So, if I have a directory like
app/controllers/my_module in my application, then
autoloadable_module? will return
MyModule as a module. If not, I’ll get an error.
Mystery solved after an interesting morning of spelunking.