Module: Zeitwerk::Loader::Callbacks
- Included in:
- Zeitwerk::Loader
- Defined in:
- lib/zeitwerk/loader/callbacks.rb
Instance Method Summary collapse
-
#on_dir_autoloaded(dir) ⇒ void
Invoked from our decorated Kernel#require when a managed directory is autoloaded.
-
#on_file_autoloaded(file) ⇒ void
Invoked from our decorated Kernel#require when a managed file is autoloaded.
-
#on_namespace_loaded(namespace) ⇒ void
Invoked when a class or module is created or reopened, either from the tracer or from module autovivification.
Instance Method Details
#on_dir_autoloaded(dir) ⇒ void
This method returns an undefined value.
Invoked from our decorated Kernel#require when a managed directory is autoloaded.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/zeitwerk/loader/callbacks.rb', line 19 def on_dir_autoloaded(dir) # Module#autoload does not serialize concurrent requires, and we handle # directories ourselves. # # That introduces a race condition here in which thread t1 autovivifies the # module, and while autoloads are being set on that module object, thread t2 # autoloads the same namespace. # # In that situation, t2 resets the constant to store a new module. That not # only sets the constant twice (undesirable per se), but it gets worse, # because the module object created by t2 won't have any of the autoloads # for child constants set, since t1 correctly deleted the lazy_dirs entry, # thus resulting in NameErrors when client code tries to reach them. mutex2.synchronize do parent, cname = autoloads[dir] break if loaded_cpaths.include?(cpath(parent, cname)) autovivified_module = parent.const_set(cname, Module.new) log("module #{autovivified_module.name} autovivified from directory #{dir}") if logger loaded_cpaths.add(autovivified_module.name) on_namespace_loaded(autovivified_module) end end |
#on_file_autoloaded(file) ⇒ void
This method returns an undefined value.
Invoked from our decorated Kernel#require when a managed file is autoloaded.
7 8 9 10 11 |
# File 'lib/zeitwerk/loader/callbacks.rb', line 7 def on_file_autoloaded(file) parent, cname = autoloads[file] loaded_cpaths.add(cpath(parent, cname)) log("constant #{cpath(parent, cname)} loaded from file #{file}") if logger end |
#on_namespace_loaded(namespace) ⇒ void
This method returns an undefined value.
Invoked when a class or module is created or reopened, either from the tracer or from module autovivification. If the namespace has matching subdirectories, we descend into them now.
51 52 53 54 55 56 57 |
# File 'lib/zeitwerk/loader/callbacks.rb', line 51 def on_namespace_loaded(namespace) if subdirs = lazy_subdirs.delete(namespace.name) subdirs.each do |subdir| set_autoloads_in_dir(subdir, namespace) end end end |