dry-rb adopts Zeitwerk for code loading

For the past few months we’ve been working on making all dry-rb gems auto-loadable through Zeitwerk. This is part of a bigger effort as Zeitwerk is also used by Hanami 2.0.

Using Zeitwerk to autoload not just your application code but also your dependencies leads to significantly faster boot times. That’s why it’s worth going through this process to have all the dry-rb gems use Zeitwerk ⚡

Updated gems

During the last few days we’ve released the following gems that now use Zeitwerk's GemLoader:

How to upgrade

In theory, everything should just work, but we’ve already found there can be various issues depending on how you require files from dry-rb gems. Luckily, the changes that may be required are very simple:

  • Change “cherry picking” requires of individual gem files (assuming you have them) to be just a single require of the gem’s entrypoint. Here's a couple of examples:
# before
require "dry/core/class_attributes"

# now
require "dry/core"

or

# before
require "dry/system/container"

# now
require "dry/system"
  • In case of dry-validation and its own dry-rb dependencies, please make sure that you upgrade everything to the current versions. Unfortunately, dry-validation 1.9.0 may still be installed with dry-schema < 1.11 due to how version requirements work in Rubygems. It’s best to have something like this in your Gemfile:

    gem "dry-validation", "~> 1.9.0"
    gem "dry-schema", "~> 1.11.2"
    
  • If you already use Zeitwerk and have teardown code in your test suite, please take a look how we’ve set it up in Hanami’s test suite to clear only the parts we need, without affecting loaders from other gems:

def autoloaders_teardown!
  # Tear down Zeitwerk (from zeitwerk's own test/support/loader_test)
  Zeitwerk::Registry.loaders.reject! do |loader|
    test_loader = loader.dirs.any? do |dir|
      dir.include?("/spec/") || dir.include?(Dir.tmpdir) ||
        dir.include?("/slices/") || dir.include?("/app")
    end

    if test_loader
      loader.unregister
      true
    else
      false
    end
  end
end

Reporting issues

If you find any crashes related to Ruby constants, please try to report them in the repository where the given missing constant is actually defined. If you’re unsure, just report them in the repository of the gem that you upgraded and gave you trouble.