Module: Zeitwerk::Registry

Defined in:
lib/zeitwerk/registry.rb

Overview

:nodoc: all

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.autoloads{String => Zeitwerk::Loader} (readonly)

Maps real paths to the loaders responsible for them.

This information is used by our decorated ‘Kernel#require` to be able to invoke callbacks and autovivify modules.

Returns:



27
28
29
# File 'lib/zeitwerk/registry.rb', line 27

def autoloads
  @autoloads
end

.inceptions{String => (String, Zeitwerk::Loader)} (readonly)

This hash table addresses an edge case in which an autoload is ignored.

For example, let’s suppose we want to autoload in a gem like this:

# lib/my_gem.rb
loader = Zeitwerk::Loader.new
loader.push_dir(__dir__)
loader.setup

module MyGem
end

if you require “my_gem”, as Bundler would do, this happens while setting up autoloads:

1. Object.autoload?(:MyGem) returns `nil` because the autoload for
   the constant is issued by Zeitwerk while the same file is being
   required.
2. The constant `MyGem` is undefined while setup runs.

Therefore, a directory ‘lib/my_gem` would autovivify a module according to the existing information. But that would be wrong.

To overcome this fundamental limitation, we keep track of the constant paths that are in this situation —in the example above, “MyGem”— and take this collection into account for the autovivification logic.

Note that you cannot generally address this by moving the setup code below the constant definition, because we want libraries to be able to use managed constants in the module body:

module MyGem
  include MyConcern
end

Returns:



66
67
68
# File 'lib/zeitwerk/registry.rb', line 66

def inceptions
  @inceptions
end

.loaders<Zeitwerk::Loader> (readonly)

Keeps track of all loaders. Useful to broadcast messages and to prevent them from being garbage collected.

Returns:



11
12
13
# File 'lib/zeitwerk/registry.rb', line 11

def loaders
  @loaders
end

.loaders_managing_gems{String => Zeitwerk::Loader} (readonly)

Registers loaders created with ‘for_gem` to make the method idempotent in case of reload.

Returns:



18
19
20
# File 'lib/zeitwerk/registry.rb', line 18

def loaders_managing_gems
  @loaders_managing_gems
end

Class Method Details

.inception?(cpath) ⇒ String?

Parameters:

  • cpath (String)

Returns:

  • (String, nil)


120
121
122
123
124
# File 'lib/zeitwerk/registry.rb', line 120

def inception?(cpath)
  if pair = inceptions[cpath]
    pair.first
  end
end

.loader_for(path) ⇒ Zeitwerk::Loader?

Parameters:

  • path (String)

Returns:



129
130
131
# File 'lib/zeitwerk/registry.rb', line 129

def loader_for(path)
  autoloads[path]
end

.loader_for_gem(root_file) ⇒ Zeitwerk::Loader

This method returns always a loader, the same instance for the same root file. That is how Zeitwerk::Loader.for_gem is idempotent.

Parameters:

  • root_file (String)

Returns:



83
84
85
86
87
88
89
90
91
# File 'lib/zeitwerk/registry.rb', line 83

def loader_for_gem(root_file)
  loaders_managing_gems[root_file] ||= begin
    Loader.new.tap do |loader|
      loader.tag = File.basename(root_file, ".rb")
      loader.inflector = GemInflector.new(root_file)
      loader.push_dir(File.dirname(root_file))
    end
  end
end

.on_unload(loader) ⇒ void

This method returns an undefined value.

Parameters:



136
137
138
139
# File 'lib/zeitwerk/registry.rb', line 136

def on_unload(loader)
  autoloads.delete_if { |_path, object| object == loader }
  inceptions.delete_if { |_cpath, (_path, object)| object == loader }
end

.register_autoload(loader, realpath) ⇒ void

This method returns an undefined value.

Parameters:



97
98
99
# File 'lib/zeitwerk/registry.rb', line 97

def register_autoload(loader, realpath)
  autoloads[realpath] = loader
end

.register_inception(cpath, realpath, loader) ⇒ void

This method returns an undefined value.

Parameters:



113
114
115
# File 'lib/zeitwerk/registry.rb', line 113

def register_inception(cpath, realpath, loader)
  inceptions[cpath] = [realpath, loader]
end

.register_loader(loader) ⇒ void

This method returns an undefined value.

Registers a loader.

Parameters:



73
74
75
# File 'lib/zeitwerk/registry.rb', line 73

def register_loader(loader)
  loaders << loader
end

.unregister_autoload(realpath) ⇒ void

This method returns an undefined value.

Parameters:

  • realpath (String)


104
105
106
# File 'lib/zeitwerk/registry.rb', line 104

def unregister_autoload(realpath)
  autoloads.delete(realpath)
end