module Zeitwerk::Loader::Callbacks

def on_dir_autoloaded(dir)

Other tags:
    Private: -
def on_dir_autoloaded(dir)
  # Module#autoload does not serialize concurrent requires in CRuby < 3.2, and
  # we handle directories ourselves without going through Kernel#require, so
  # the callback needs to account for concurrency.
  #
  # Multi-threading would introduce a race condition here in which thread t1
  # autovivifies the module, and while autoloads for its children are being
  # set, thread t2 autoloads the same namespace.
  #
  # Without the mutex and subsequent delete call, t2 would reset the module.
  # That not only would reassign the constant (undesirable per se) but, worse,
  # the module object created by t2 wouldn't have any of the autoloads for its
  # children, since t1 would have correctly deleted its namespace_dirs entry.
  dirs_autoload_monitor.synchronize do
    if cref = autoloads.delete(dir)
      autovivified_module = cref[0].const_set(cref[1], Module.new)
      cpath = autovivified_module.name
      log("module #{cpath} autovivified from directory #{dir}") if logger
      to_unload[cpath] = [dir, cref] if reloading_enabled?
      # We don't unregister `dir` in the registry because concurrent threads
      # wouldn't find a loader associated to it in Kernel#require and would
      # try to require the directory. Instead, we are going to keep track of
      # these to be able to unregister later if eager loading.
      autoloaded_dirs << dir
      on_namespace_loaded(autovivified_module)
      run_on_load_callbacks(cpath, autovivified_module, dir) unless on_load_callbacks.empty?
    end
  end
end

def on_file_autoloaded(file)

Other tags:
    Private: -
def on_file_autoloaded(file)
  cref  = autoloads.delete(file)
  cpath = cpath(*cref)
  Zeitwerk::Registry.unregister_autoload(file)
  if cdef?(*cref)
    log("constant #{cpath} loaded from file #{file}") if logger
    to_unload[cpath] = [file, cref] if reloading_enabled?
    run_on_load_callbacks(cpath, cget(*cref), file) unless on_load_callbacks.empty?
  else
    msg = "expected file #{file} to define constant #{cpath}, but didn't"
    log(msg) if logger
    crem(*cref)
    to_unload[cpath] = [file, cref] if reloading_enabled?
    raise Zeitwerk::NameError.new(msg, cref.last)
  end
end

def on_namespace_loaded(namespace)

Other tags:
    Private: -
def on_namespace_loaded(namespace)
  if dirs = namespace_dirs.delete(real_mod_name(namespace))
    dirs.each do |dir|
      set_autoloads_in_dir(dir, namespace)
    end
  end
end

def run_on_load_callbacks(cpath, value, abspath)

@sig (String, Object) -> void
def run_on_load_callbacks(cpath, value, abspath)
  # Order matters. If present, run the most specific one.
  callbacks = reloading_enabled? ? on_load_callbacks[cpath] : on_load_callbacks.delete(cpath)
  callbacks&.each { |c| c.call(value, abspath) }
  callbacks = on_load_callbacks[:ANY]
  callbacks&.each { |c| c.call(cpath, value, abspath) }
end