Zeitwerk & Module Autoloading in Ruby (Explained Clearly)

This article explains class & module autoloading in Ruby. Including the new “Zeitwerk” gem which is part of Rails 6.

Let’s start with a question…

How do we bring together multiple source code files into one?

We require them.

Requiring a file makes Ruby read it & run the code inside. But if we have a list of required files we probably don’t need to load ALL of them.

At least not right away…

How can we load files only when we need them so we can start our application faster?

That’s where autoloading comes in!

How to Use Autoloading

Ruby has a built-in autoloading feature.

It’s based on constants.

When a constant like Coconut is found for the first time, Ruby will try to load its associated file.

But first:

You need to register this constant with its file name.

Like this:

autoload :Coconut, "lib/coconut.rb"

Now Ruby knows where to look whenever you want to use the Coconut class or module.

But you know what would be even better?

Imagine if you didn’t have to register constants manually & Ruby knew exactly where to find everything.

Well…

This is what Rails does, but before Rails 6 it didn’t use this autoload mechanism.

Autoloading in Rails BEFORE Rails 6

I don’t fully understand how it works, but Rails uses const_missing, instead of autoload to automatically find & load files into your project.

Why is that useful?

Because it means you don’t have to use require in your Rails projects.

Convention over configuration…

It all happens automatically, given that you follow the rules.

The rules are:

  1. Put your file where it can be found (as defined by ActiveSupport::Dependencies.autoload_paths)
  2. Define one class / module per file
  3. Name the file after the class name, using underscores (UsersController => users_controller)

Then…

Whenever your code references any of these class names, Rails will know where to find them.

Very helpful.

Autoloading in Rails AFTER Rails 6

Rails 6 introduces a new constant autoloading mechanism.

It’s called Zeitwerk.

How is this different from “classic” Rails autoloading?

Unlike the const_missing approach used by older Rails versions, which lacks information – like module nesting – resulting in a number of limitations.

Zeitwerk uses Ruby’s autoload.

This new implementation follows similar file-naming conventions.

In fact:

Zeitwerk uses the file name to infer the class name, users_controller => UsersController.

Which is exactly the opposite of before.

Btw, you can still use autoload_paths, but you only want to add BASE paths, like "/lib", instead of "/lib/**".

Why?

It’s the way this works with namespaces & nesting.

  • If you have "lib" in autoload, and you want to define "Fruit::Orange", then the file name has to be "lib/fruit/orange.rb".
  • But if you have "lib/fruit" in autoload, then you would have to use another folder, so your file name becomes "lib/fruit/fruit/orange.rb" for the same class.

The best part?

This new functionality isn’t glued to Rails, so you can use it in your non-Rails projects!

Summary

You have learned about module autoloading in Ruby, exactly what it is & how it works!

With this new understanding, you’ll be able to structure your Ruby projects in the most effective way.

It’s your turn, open up your editor & have some fun.

Thanks for reading! 🙂

6 thoughts on “Zeitwerk & Module Autoloading in Ruby (Explained Clearly)”

  1. Thank you for this article, i’ve struggled with this on Rails 6.0.0.rc2 but this article makes things clear about autoloading.

Comments are closed.