lib/zeitwerk/loader/callbacks.rb in zeitwerk-2.4.1 vs lib/zeitwerk/loader/callbacks.rb in zeitwerk-2.4.2

- old
+ new

@@ -4,19 +4,23 @@ # Invoked from our decorated Kernel#require when a managed file is autoloaded. # # @private # @sig (String) -> void def on_file_autoloaded(file) - cref = autoloads.delete(file) - to_unload[cpath(*cref)] = [file, cref] if reloading_enabled? + cref = autoloads.delete(file) + cpath = cpath(*cref) + + to_unload[cpath] = [file, cref] if reloading_enabled? Zeitwerk::Registry.unregister_autoload(file) if logger && cdef?(*cref) - log("constant #{cpath(*cref)} loaded from file #{file}") + log("constant #{cpath} loaded from file #{file}") elsif !cdef?(*cref) - raise Zeitwerk::NameError.new("expected file #{file} to define constant #{cpath(*cref)}, but didn't", cref.last) + raise Zeitwerk::NameError.new("expected file #{file} to define constant #{cpath}, but didn't", cref.last) end + + run_on_load_callbacks(cpath) end # Invoked from our decorated Kernel#require when a managed directory is # autoloaded. # @@ -35,21 +39,24 @@ # the module object created by t2 wouldn't have any of the autoloads for its # children, since t1 would have correctly deleted its lazy_subdirs entry. mutex2.synchronize do if cref = autoloads.delete(dir) autovivified_module = cref[0].const_set(cref[1], Module.new) - log("module #{autovivified_module.name} autovivified from directory #{dir}") if logger + cpath = autovivified_module.name + log("module #{cpath} autovivified from directory #{dir}") if logger - to_unload[autovivified_module.name] = [dir, cref] if reloading_enabled? + 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) end end end # Invoked when a class or module is created or reopened, either from the @@ -62,7 +69,18 @@ if subdirs = lazy_subdirs.delete(real_mod_name(namespace)) subdirs.each do |subdir| set_autoloads_in_dir(subdir, namespace) end end + end + + private + + # @sig (String) -> void + def run_on_load_callbacks(cpath) + # Very common, do not even compute a hash code. + return if on_load_callbacks.empty? + + callbacks = reloading_enabled? ? on_load_callbacks[cpath] : on_load_callbacks.delete(cpath) + callbacks.each(&:call) if callbacks end end