zeitwerk 2.6.7 → 2.6.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +230 -24
 - data/lib/zeitwerk/cref.rb +99 -0
 - data/lib/zeitwerk/gem_inflector.rb +2 -2
 - data/lib/zeitwerk/gem_loader.rb +11 -8
 - data/lib/zeitwerk/kernel.rb +3 -7
 - data/lib/zeitwerk/loader/callbacks.rb +29 -22
 - data/lib/zeitwerk/loader/config.rb +7 -8
 - data/lib/zeitwerk/loader/eager_load.rb +21 -17
 - data/lib/zeitwerk/loader/helpers.rb +61 -56
 - data/lib/zeitwerk/loader.rb +186 -94
 - data/lib/zeitwerk/null_inflector.rb +5 -0
 - data/lib/zeitwerk/registry.rb +7 -4
 - data/lib/zeitwerk/version.rb +1 -1
 - data/lib/zeitwerk.rb +2 -0
 - metadata +5 -3
 
    
        data/lib/zeitwerk/loader.rb
    CHANGED
    
    | 
         @@ -1,5 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require "monitor"
         
     | 
| 
       3 
4 
     | 
    
         
             
            require "set"
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module Zeitwerk
         
     | 
| 
         @@ -21,14 +22,13 @@ module Zeitwerk 
     | 
|
| 
       21 
22 
     | 
    
         
             
                private_constant :MUTEX
         
     | 
| 
       22 
23 
     | 
    
         | 
| 
       23 
24 
     | 
    
         
             
                # Maps absolute paths for which an autoload has been set ---and not
         
     | 
| 
       24 
     | 
    
         
            -
                # executed--- to their corresponding  
     | 
| 
       25 
     | 
    
         
            -
                # name.
         
     | 
| 
      
 25 
     | 
    
         
            +
                # executed--- to their corresponding Zeitwerk::Cref object.
         
     | 
| 
       26 
26 
     | 
    
         
             
                #
         
     | 
| 
       27 
     | 
    
         
            -
                #   "/Users/fxn/blog/app/models/user.rb"          =>  
     | 
| 
       28 
     | 
    
         
            -
                #   "/Users/fxn/blog/app/models/hotel/pricing.rb" =>  
     | 
| 
      
 27 
     | 
    
         
            +
                #   "/Users/fxn/blog/app/models/user.rb"          => #<Zeitwerk::Cref:... @mod=Object, @cname=:User, ...>,
         
     | 
| 
      
 28 
     | 
    
         
            +
                #   "/Users/fxn/blog/app/models/hotel/pricing.rb" => #<Zeitwerk::Cref:... @mod=Hotel, @cname=:Pricing, ...>,
         
     | 
| 
       29 
29 
     | 
    
         
             
                #   ...
         
     | 
| 
       30 
30 
     | 
    
         
             
                #
         
     | 
| 
       31 
     | 
    
         
            -
                # @sig Hash[String,  
     | 
| 
      
 31 
     | 
    
         
            +
                # @sig Hash[String, Zeitwerk::Cref]
         
     | 
| 
       32 
32 
     | 
    
         
             
                attr_reader :autoloads
         
     | 
| 
       33 
33 
     | 
    
         
             
                internal :autoloads
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
         @@ -44,17 +44,19 @@ module Zeitwerk 
     | 
|
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                # Stores metadata needed for unloading. Its entries look like this:
         
     | 
| 
       46 
46 
     | 
    
         
             
                #
         
     | 
| 
       47 
     | 
    
         
            -
                #   "Admin::Role" => [ 
     | 
| 
      
 47 
     | 
    
         
            +
                #   "Admin::Role" => [
         
     | 
| 
      
 48 
     | 
    
         
            +
                #     ".../admin/role.rb",
         
     | 
| 
      
 49 
     | 
    
         
            +
                #     #<Zeitwerk::Cref:... @mod=Admin, @cname=:Role, ...>
         
     | 
| 
      
 50 
     | 
    
         
            +
                #   ]
         
     | 
| 
       48 
51 
     | 
    
         
             
                #
         
     | 
| 
       49 
52 
     | 
    
         
             
                # The cpath as key helps implementing unloadable_cpath? The file name is
         
     | 
| 
       50 
53 
     | 
    
         
             
                # stored in order to be able to delete it from $LOADED_FEATURES, and the
         
     | 
| 
       51 
     | 
    
         
            -
                #  
     | 
| 
       52 
     | 
    
         
            -
                # or module object.
         
     | 
| 
      
 54 
     | 
    
         
            +
                # cref is used to remove the constant from the parent class or module.
         
     | 
| 
       53 
55 
     | 
    
         
             
                #
         
     | 
| 
       54 
56 
     | 
    
         
             
                # If reloading is enabled, this hash is filled as constants are autoloaded
         
     | 
| 
       55 
57 
     | 
    
         
             
                # or eager loaded. Otherwise, the collection remains empty.
         
     | 
| 
       56 
58 
     | 
    
         
             
                #
         
     | 
| 
       57 
     | 
    
         
            -
                # @sig Hash[String, [String,  
     | 
| 
      
 59 
     | 
    
         
            +
                # @sig Hash[String, [String, Zeitwerk::Cref]]
         
     | 
| 
       58 
60 
     | 
    
         
             
                attr_reader :to_unload
         
     | 
| 
       59 
61 
     | 
    
         
             
                internal :to_unload
         
     | 
| 
       60 
62 
     | 
    
         | 
| 
         @@ -91,9 +93,9 @@ module Zeitwerk 
     | 
|
| 
       91 
93 
     | 
    
         
             
                attr_reader :mutex
         
     | 
| 
       92 
94 
     | 
    
         
             
                private :mutex
         
     | 
| 
       93 
95 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
                # @sig  
     | 
| 
       95 
     | 
    
         
            -
                attr_reader : 
     | 
| 
       96 
     | 
    
         
            -
                private : 
     | 
| 
      
 96 
     | 
    
         
            +
                # @sig Monitor
         
     | 
| 
      
 97 
     | 
    
         
            +
                attr_reader :dirs_autoload_monitor
         
     | 
| 
      
 98 
     | 
    
         
            +
                private :dirs_autoload_monitor
         
     | 
| 
       97 
99 
     | 
    
         | 
| 
       98 
100 
     | 
    
         
             
                def initialize
         
     | 
| 
       99 
101 
     | 
    
         
             
                  super
         
     | 
| 
         @@ -103,11 +105,12 @@ module Zeitwerk 
     | 
|
| 
       103 
105 
     | 
    
         
             
                  @to_unload       = {}
         
     | 
| 
       104 
106 
     | 
    
         
             
                  @namespace_dirs  = Hash.new { |h, cpath| h[cpath] = [] }
         
     | 
| 
       105 
107 
     | 
    
         
             
                  @shadowed_files  = Set.new
         
     | 
| 
       106 
     | 
    
         
            -
                  @mutex           = Mutex.new
         
     | 
| 
       107 
     | 
    
         
            -
                  @mutex2          = Mutex.new
         
     | 
| 
       108 
108 
     | 
    
         
             
                  @setup           = false
         
     | 
| 
       109 
109 
     | 
    
         
             
                  @eager_loaded    = false
         
     | 
| 
       110 
110 
     | 
    
         | 
| 
      
 111 
     | 
    
         
            +
                  @mutex = Mutex.new
         
     | 
| 
      
 112 
     | 
    
         
            +
                  @dirs_autoload_monitor = Monitor.new
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
       111 
114 
     | 
    
         
             
                  Registry.register_loader(self)
         
     | 
| 
       112 
115 
     | 
    
         
             
                end
         
     | 
| 
       113 
116 
     | 
    
         | 
| 
         @@ -119,7 +122,7 @@ module Zeitwerk 
     | 
|
| 
       119 
122 
     | 
    
         
             
                    break if @setup
         
     | 
| 
       120 
123 
     | 
    
         | 
| 
       121 
124 
     | 
    
         
             
                    actual_roots.each do |root_dir, root_namespace|
         
     | 
| 
       122 
     | 
    
         
            -
                       
     | 
| 
      
 125 
     | 
    
         
            +
                      define_autoloads_for_dir(root_dir, root_namespace)
         
     | 
| 
       123 
126 
     | 
    
         
             
                    end
         
     | 
| 
       124 
127 
     | 
    
         | 
| 
       125 
128 
     | 
    
         
             
                    on_setup_callbacks.each(&:call)
         
     | 
| 
         @@ -152,22 +155,22 @@ module Zeitwerk 
     | 
|
| 
       152 
155 
     | 
    
         
             
                    # is enough.
         
     | 
| 
       153 
156 
     | 
    
         
             
                    unloaded_files = Set.new
         
     | 
| 
       154 
157 
     | 
    
         | 
| 
       155 
     | 
    
         
            -
                    autoloads.each do |abspath,  
     | 
| 
       156 
     | 
    
         
            -
                      if  
     | 
| 
       157 
     | 
    
         
            -
                        unload_autoload( 
     | 
| 
      
 158 
     | 
    
         
            +
                    autoloads.each do |abspath, cref|
         
     | 
| 
      
 159 
     | 
    
         
            +
                      if cref.autoload?
         
     | 
| 
      
 160 
     | 
    
         
            +
                        unload_autoload(cref)
         
     | 
| 
       158 
161 
     | 
    
         
             
                      else
         
     | 
| 
       159 
162 
     | 
    
         
             
                        # Could happen if loaded with require_relative. That is unsupported,
         
     | 
| 
       160 
163 
     | 
    
         
             
                        # and the constant path would escape unloadable_cpath? This is just
         
     | 
| 
       161 
164 
     | 
    
         
             
                        # defensive code to clean things up as much as we are able to.
         
     | 
| 
       162 
     | 
    
         
            -
                        unload_cref( 
     | 
| 
      
 165 
     | 
    
         
            +
                        unload_cref(cref)
         
     | 
| 
       163 
166 
     | 
    
         
             
                        unloaded_files.add(abspath) if ruby?(abspath)
         
     | 
| 
       164 
167 
     | 
    
         
             
                      end
         
     | 
| 
       165 
168 
     | 
    
         
             
                    end
         
     | 
| 
       166 
169 
     | 
    
         | 
| 
       167 
     | 
    
         
            -
                    to_unload.each do |cpath, (abspath,  
     | 
| 
      
 170 
     | 
    
         
            +
                    to_unload.each do |cpath, (abspath, cref)|
         
     | 
| 
       168 
171 
     | 
    
         
             
                      unless on_unload_callbacks.empty?
         
     | 
| 
       169 
172 
     | 
    
         
             
                        begin
         
     | 
| 
       170 
     | 
    
         
            -
                          value =  
     | 
| 
      
 173 
     | 
    
         
            +
                          value = cref.get
         
     | 
| 
       171 
174 
     | 
    
         
             
                        rescue ::NameError
         
     | 
| 
       172 
175 
     | 
    
         
             
                          # Perhaps the user deleted the constant by hand, or perhaps an
         
     | 
| 
       173 
176 
     | 
    
         
             
                          # autoload failed to define the expected constant but the user
         
     | 
| 
         @@ -177,7 +180,7 @@ module Zeitwerk 
     | 
|
| 
       177 
180 
     | 
    
         
             
                        end
         
     | 
| 
       178 
181 
     | 
    
         
             
                      end
         
     | 
| 
       179 
182 
     | 
    
         | 
| 
       180 
     | 
    
         
            -
                      unload_cref( 
     | 
| 
      
 183 
     | 
    
         
            +
                      unload_cref(cref)
         
     | 
| 
       181 
184 
     | 
    
         
             
                      unloaded_files.add(abspath) if ruby?(abspath)
         
     | 
| 
       182 
185 
     | 
    
         
             
                    end
         
     | 
| 
       183 
186 
     | 
    
         | 
| 
         @@ -228,6 +231,87 @@ module Zeitwerk 
     | 
|
| 
       228 
231 
     | 
    
         
             
                  setup
         
     | 
| 
       229 
232 
     | 
    
         
             
                end
         
     | 
| 
       230 
233 
     | 
    
         | 
| 
      
 234 
     | 
    
         
            +
                # Returns a hash that maps the absolute paths of the managed files and
         
     | 
| 
      
 235 
     | 
    
         
            +
                # directories to their respective expected constant paths.
         
     | 
| 
      
 236 
     | 
    
         
            +
                #
         
     | 
| 
      
 237 
     | 
    
         
            +
                # @sig () -> Hash[String, String]
         
     | 
| 
      
 238 
     | 
    
         
            +
                def all_expected_cpaths
         
     | 
| 
      
 239 
     | 
    
         
            +
                  result = {}
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
                  actual_roots.each do |root_dir, root_namespace|
         
     | 
| 
      
 242 
     | 
    
         
            +
                    queue = [[root_dir, real_mod_name(root_namespace)]]
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                    while (dir, cpath = queue.shift)
         
     | 
| 
      
 245 
     | 
    
         
            +
                      result[dir] = cpath
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
      
 247 
     | 
    
         
            +
                      prefix = cpath == "Object" ? "" : cpath + "::"
         
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
                      ls(dir) do |basename, abspath, ftype|
         
     | 
| 
      
 250 
     | 
    
         
            +
                        if ftype == :file
         
     | 
| 
      
 251 
     | 
    
         
            +
                          basename.delete_suffix!(".rb")
         
     | 
| 
      
 252 
     | 
    
         
            +
                          result[abspath] = prefix + inflector.camelize(basename, abspath)
         
     | 
| 
      
 253 
     | 
    
         
            +
                        else
         
     | 
| 
      
 254 
     | 
    
         
            +
                          if collapse?(abspath)
         
     | 
| 
      
 255 
     | 
    
         
            +
                            queue << [abspath, cpath]
         
     | 
| 
      
 256 
     | 
    
         
            +
                          else
         
     | 
| 
      
 257 
     | 
    
         
            +
                            queue << [abspath, prefix + inflector.camelize(basename, abspath)]
         
     | 
| 
      
 258 
     | 
    
         
            +
                          end
         
     | 
| 
      
 259 
     | 
    
         
            +
                        end
         
     | 
| 
      
 260 
     | 
    
         
            +
                      end
         
     | 
| 
      
 261 
     | 
    
         
            +
                    end
         
     | 
| 
      
 262 
     | 
    
         
            +
                  end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                  result
         
     | 
| 
      
 265 
     | 
    
         
            +
                end
         
     | 
| 
      
 266 
     | 
    
         
            +
             
     | 
| 
      
 267 
     | 
    
         
            +
                # @sig (String | Pathname) -> String?
         
     | 
| 
      
 268 
     | 
    
         
            +
                def cpath_expected_at(path)
         
     | 
| 
      
 269 
     | 
    
         
            +
                  abspath = File.expand_path(path)
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
                  raise Zeitwerk::Error.new("#{abspath} does not exist") unless File.exist?(abspath)
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
                  return unless dir?(abspath) || ruby?(abspath)
         
     | 
| 
      
 274 
     | 
    
         
            +
                  return if ignored_path?(abspath)
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
                  paths = []
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
                  if ruby?(abspath)
         
     | 
| 
      
 279 
     | 
    
         
            +
                    basename = File.basename(abspath, ".rb")
         
     | 
| 
      
 280 
     | 
    
         
            +
                    return if hidden?(basename)
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
                    paths << [basename, abspath]
         
     | 
| 
      
 283 
     | 
    
         
            +
                    walk_up_from = File.dirname(abspath)
         
     | 
| 
      
 284 
     | 
    
         
            +
                  else
         
     | 
| 
      
 285 
     | 
    
         
            +
                    walk_up_from = abspath
         
     | 
| 
      
 286 
     | 
    
         
            +
                  end
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
                  root_namespace = nil
         
     | 
| 
      
 289 
     | 
    
         
            +
             
     | 
| 
      
 290 
     | 
    
         
            +
                  walk_up(walk_up_from) do |dir|
         
     | 
| 
      
 291 
     | 
    
         
            +
                    break if root_namespace = roots[dir]
         
     | 
| 
      
 292 
     | 
    
         
            +
                    return if ignored_path?(dir)
         
     | 
| 
      
 293 
     | 
    
         
            +
             
     | 
| 
      
 294 
     | 
    
         
            +
                    basename = File.basename(dir)
         
     | 
| 
      
 295 
     | 
    
         
            +
                    return if hidden?(basename)
         
     | 
| 
      
 296 
     | 
    
         
            +
             
     | 
| 
      
 297 
     | 
    
         
            +
                    paths << [basename, abspath] unless collapse?(dir)
         
     | 
| 
      
 298 
     | 
    
         
            +
                  end
         
     | 
| 
      
 299 
     | 
    
         
            +
             
     | 
| 
      
 300 
     | 
    
         
            +
                  return unless root_namespace
         
     | 
| 
      
 301 
     | 
    
         
            +
             
     | 
| 
      
 302 
     | 
    
         
            +
                  if paths.empty?
         
     | 
| 
      
 303 
     | 
    
         
            +
                    real_mod_name(root_namespace)
         
     | 
| 
      
 304 
     | 
    
         
            +
                  else
         
     | 
| 
      
 305 
     | 
    
         
            +
                    cnames = paths.reverse_each.map { |b, a| cname_for(b, a) }
         
     | 
| 
      
 306 
     | 
    
         
            +
             
     | 
| 
      
 307 
     | 
    
         
            +
                    if root_namespace == Object
         
     | 
| 
      
 308 
     | 
    
         
            +
                      cnames.join("::")
         
     | 
| 
      
 309 
     | 
    
         
            +
                    else
         
     | 
| 
      
 310 
     | 
    
         
            +
                      "#{real_mod_name(root_namespace)}::#{cnames.join("::")}"
         
     | 
| 
      
 311 
     | 
    
         
            +
                    end
         
     | 
| 
      
 312 
     | 
    
         
            +
                  end
         
     | 
| 
      
 313 
     | 
    
         
            +
                end
         
     | 
| 
      
 314 
     | 
    
         
            +
             
     | 
| 
       231 
315 
     | 
    
         
             
                # Says if the given constant path would be unloaded on reload. This
         
     | 
| 
       232 
316 
     | 
    
         
             
                # predicate returns `false` if reloading is disabled.
         
     | 
| 
       233 
317 
     | 
    
         
             
                #
         
     | 
| 
         @@ -264,12 +348,15 @@ module Zeitwerk 
     | 
|
| 
       264 
348 
     | 
    
         
             
                # --- Class methods ---------------------------------------------------------------------------
         
     | 
| 
       265 
349 
     | 
    
         | 
| 
       266 
350 
     | 
    
         
             
                class << self
         
     | 
| 
      
 351 
     | 
    
         
            +
                  include RealModName
         
     | 
| 
      
 352 
     | 
    
         
            +
             
     | 
| 
       267 
353 
     | 
    
         
             
                  # @sig #call | #debug | nil
         
     | 
| 
       268 
354 
     | 
    
         
             
                  attr_accessor :default_logger
         
     | 
| 
       269 
355 
     | 
    
         | 
| 
       270 
356 
     | 
    
         
             
                  # This is a shortcut for
         
     | 
| 
       271 
357 
     | 
    
         
             
                  #
         
     | 
| 
       272 
358 
     | 
    
         
             
                  #   require "zeitwerk"
         
     | 
| 
      
 359 
     | 
    
         
            +
                  #
         
     | 
| 
       273 
360 
     | 
    
         
             
                  #   loader = Zeitwerk::Loader.new
         
     | 
| 
       274 
361 
     | 
    
         
             
                  #   loader.tag = File.basename(__FILE__, ".rb")
         
     | 
| 
       275 
362 
     | 
    
         
             
                  #   loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
         
     | 
| 
         @@ -284,7 +371,36 @@ module Zeitwerk 
     | 
|
| 
       284 
371 
     | 
    
         
             
                  # @sig (bool) -> Zeitwerk::GemLoader
         
     | 
| 
       285 
372 
     | 
    
         
             
                  def for_gem(warn_on_extra_files: true)
         
     | 
| 
       286 
373 
     | 
    
         
             
                    called_from = caller_locations(1, 1).first.path
         
     | 
| 
       287 
     | 
    
         
            -
                    Registry.loader_for_gem(called_from, warn_on_extra_files: warn_on_extra_files)
         
     | 
| 
      
 374 
     | 
    
         
            +
                    Registry.loader_for_gem(called_from, namespace: Object, warn_on_extra_files: warn_on_extra_files)
         
     | 
| 
      
 375 
     | 
    
         
            +
                  end
         
     | 
| 
      
 376 
     | 
    
         
            +
             
     | 
| 
      
 377 
     | 
    
         
            +
                  # This is a shortcut for
         
     | 
| 
      
 378 
     | 
    
         
            +
                  #
         
     | 
| 
      
 379 
     | 
    
         
            +
                  #   require "zeitwerk"
         
     | 
| 
      
 380 
     | 
    
         
            +
                  #
         
     | 
| 
      
 381 
     | 
    
         
            +
                  #   loader = Zeitwerk::Loader.new
         
     | 
| 
      
 382 
     | 
    
         
            +
                  #   loader.tag = namespace.name + "-" + File.basename(__FILE__, ".rb")
         
     | 
| 
      
 383 
     | 
    
         
            +
                  #   loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
         
     | 
| 
      
 384 
     | 
    
         
            +
                  #   loader.push_dir(__dir__, namespace: namespace)
         
     | 
| 
      
 385 
     | 
    
         
            +
                  #
         
     | 
| 
      
 386 
     | 
    
         
            +
                  # except that this method returns the same object in subsequent calls from
         
     | 
| 
      
 387 
     | 
    
         
            +
                  # the same file, in the unlikely case the gem wants to be able to reload.
         
     | 
| 
      
 388 
     | 
    
         
            +
                  #
         
     | 
| 
      
 389 
     | 
    
         
            +
                  # This method returns a subclass of Zeitwerk::Loader, but the exact type
         
     | 
| 
      
 390 
     | 
    
         
            +
                  # is private, client code can only rely on the interface.
         
     | 
| 
      
 391 
     | 
    
         
            +
                  #
         
     | 
| 
      
 392 
     | 
    
         
            +
                  # @sig (bool) -> Zeitwerk::GemLoader
         
     | 
| 
      
 393 
     | 
    
         
            +
                  def for_gem_extension(namespace)
         
     | 
| 
      
 394 
     | 
    
         
            +
                    unless namespace.is_a?(Module) # Note that Class < Module.
         
     | 
| 
      
 395 
     | 
    
         
            +
                      raise Zeitwerk::Error, "#{namespace.inspect} is not a class or module object, should be"
         
     | 
| 
      
 396 
     | 
    
         
            +
                    end
         
     | 
| 
      
 397 
     | 
    
         
            +
             
     | 
| 
      
 398 
     | 
    
         
            +
                    unless real_mod_name(namespace)
         
     | 
| 
      
 399 
     | 
    
         
            +
                      raise Zeitwerk::Error, "extending anonymous namespaces is unsupported"
         
     | 
| 
      
 400 
     | 
    
         
            +
                    end
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
      
 402 
     | 
    
         
            +
                    called_from = caller_locations(1, 1).first.path
         
     | 
| 
      
 403 
     | 
    
         
            +
                    Registry.loader_for_gem(called_from, namespace: namespace, warn_on_extra_files: false)
         
     | 
| 
       288 
404 
     | 
    
         
             
                  end
         
     | 
| 
       289 
405 
     | 
    
         | 
| 
       290 
406 
     | 
    
         
             
                  # Broadcasts `eager_load` to all loaders. Those that have not been setup
         
     | 
| 
         @@ -325,44 +441,26 @@ module Zeitwerk 
     | 
|
| 
       325 
441 
     | 
    
         
             
                end
         
     | 
| 
       326 
442 
     | 
    
         | 
| 
       327 
443 
     | 
    
         
             
                # @sig (String, Module) -> void
         
     | 
| 
       328 
     | 
    
         
            -
                private def  
     | 
| 
       329 
     | 
    
         
            -
                  ls(dir) do |basename, abspath|
         
     | 
| 
       330 
     | 
    
         
            -
                     
     | 
| 
       331 
     | 
    
         
            -
                       
     | 
| 
       332 
     | 
    
         
            -
             
     | 
| 
       333 
     | 
    
         
            -
             
     | 
| 
       334 
     | 
    
         
            -
             
     | 
| 
      
 444 
     | 
    
         
            +
                private def define_autoloads_for_dir(dir, parent)
         
     | 
| 
      
 445 
     | 
    
         
            +
                  ls(dir) do |basename, abspath, ftype|
         
     | 
| 
      
 446 
     | 
    
         
            +
                    if ftype == :file
         
     | 
| 
      
 447 
     | 
    
         
            +
                      basename.delete_suffix!(".rb")
         
     | 
| 
      
 448 
     | 
    
         
            +
                      cref = Cref.new(parent, cname_for(basename, abspath))
         
     | 
| 
      
 449 
     | 
    
         
            +
                      autoload_file(cref, abspath)
         
     | 
| 
      
 450 
     | 
    
         
            +
                    else
         
     | 
| 
      
 451 
     | 
    
         
            +
                      if collapse?(abspath)
         
     | 
| 
      
 452 
     | 
    
         
            +
                        define_autoloads_for_dir(abspath, parent)
         
     | 
| 
       335 
453 
     | 
    
         
             
                      else
         
     | 
| 
       336 
     | 
    
         
            -
                         
     | 
| 
       337 
     | 
    
         
            -
             
     | 
| 
       338 
     | 
    
         
            -
                        else
         
     | 
| 
       339 
     | 
    
         
            -
                          cname = inflector.camelize(basename, abspath).to_sym
         
     | 
| 
       340 
     | 
    
         
            -
                          autoload_subdir(parent, cname, abspath)
         
     | 
| 
       341 
     | 
    
         
            -
                        end
         
     | 
| 
      
 454 
     | 
    
         
            +
                        cref = Cref.new(parent, cname_for(basename, abspath))
         
     | 
| 
      
 455 
     | 
    
         
            +
                        autoload_subdir(cref, abspath)
         
     | 
| 
       342 
456 
     | 
    
         
             
                      end
         
     | 
| 
       343 
     | 
    
         
            -
                    rescue ::NameError => error
         
     | 
| 
       344 
     | 
    
         
            -
                      path_type = ruby?(abspath) ? "file" : "directory"
         
     | 
| 
       345 
     | 
    
         
            -
             
     | 
| 
       346 
     | 
    
         
            -
                      raise NameError.new(<<~MESSAGE, error.name)
         
     | 
| 
       347 
     | 
    
         
            -
                        #{error.message} inferred by #{inflector.class} from #{path_type}
         
     | 
| 
       348 
     | 
    
         
            -
             
     | 
| 
       349 
     | 
    
         
            -
                          #{abspath}
         
     | 
| 
       350 
     | 
    
         
            -
             
     | 
| 
       351 
     | 
    
         
            -
                        Possible ways to address this:
         
     | 
| 
       352 
     | 
    
         
            -
             
     | 
| 
       353 
     | 
    
         
            -
                          * Tell Zeitwerk to ignore this particular #{path_type}.
         
     | 
| 
       354 
     | 
    
         
            -
                          * Tell Zeitwerk to ignore one of its parent directories.
         
     | 
| 
       355 
     | 
    
         
            -
                          * Rename the #{path_type} to comply with the naming conventions.
         
     | 
| 
       356 
     | 
    
         
            -
                          * Modify the inflector to handle this case.
         
     | 
| 
       357 
     | 
    
         
            -
                      MESSAGE
         
     | 
| 
       358 
457 
     | 
    
         
             
                    end
         
     | 
| 
       359 
458 
     | 
    
         
             
                  end
         
     | 
| 
       360 
459 
     | 
    
         
             
                end
         
     | 
| 
       361 
460 
     | 
    
         | 
| 
       362 
461 
     | 
    
         
             
                # @sig (Module, Symbol, String) -> void
         
     | 
| 
       363 
     | 
    
         
            -
                private def autoload_subdir( 
     | 
| 
       364 
     | 
    
         
            -
                  if autoload_path = autoload_path_set_by_me_for?( 
     | 
| 
       365 
     | 
    
         
            -
                    cpath = cpath(parent, cname)
         
     | 
| 
      
 462 
     | 
    
         
            +
                private def autoload_subdir(cref, subdir)
         
     | 
| 
      
 463 
     | 
    
         
            +
                  if autoload_path = autoload_path_set_by_me_for?(cref)
         
     | 
| 
       366 
464 
     | 
    
         
             
                    if ruby?(autoload_path)
         
     | 
| 
       367 
465 
     | 
    
         
             
                      # Scanning visited a Ruby file first, and now a directory for the same
         
     | 
| 
       368 
466 
     | 
    
         
             
                      # constant has been found. This means we are dealing with an explicit
         
     | 
| 
         @@ -371,88 +469,83 @@ module Zeitwerk 
     | 
|
| 
       371 
469 
     | 
    
         
             
                      # Registering is idempotent, and we have to keep the autoload pointing
         
     | 
| 
       372 
470 
     | 
    
         
             
                      # to the file. This may run again if more directories are found later
         
     | 
| 
       373 
471 
     | 
    
         
             
                      # on, no big deal.
         
     | 
| 
       374 
     | 
    
         
            -
                      register_explicit_namespace( 
     | 
| 
      
 472 
     | 
    
         
            +
                      register_explicit_namespace(cref.path)
         
     | 
| 
       375 
473 
     | 
    
         
             
                    end
         
     | 
| 
       376 
474 
     | 
    
         
             
                    # If the existing autoload points to a file, it has to be preserved, if
         
     | 
| 
       377 
475 
     | 
    
         
             
                    # not, it is fine as it is. In either case, we do not need to override.
         
     | 
| 
       378 
476 
     | 
    
         
             
                    # Just remember the subdirectory conforms this namespace.
         
     | 
| 
       379 
     | 
    
         
            -
                    namespace_dirs[ 
     | 
| 
       380 
     | 
    
         
            -
                  elsif ! 
     | 
| 
      
 477 
     | 
    
         
            +
                    namespace_dirs[cref.path] << subdir
         
     | 
| 
      
 478 
     | 
    
         
            +
                  elsif !cref.defined?
         
     | 
| 
       381 
479 
     | 
    
         
             
                    # First time we find this namespace, set an autoload for it.
         
     | 
| 
       382 
     | 
    
         
            -
                    namespace_dirs[ 
     | 
| 
       383 
     | 
    
         
            -
                     
     | 
| 
      
 480 
     | 
    
         
            +
                    namespace_dirs[cref.path] << subdir
         
     | 
| 
      
 481 
     | 
    
         
            +
                    define_autoload(cref, subdir)
         
     | 
| 
       384 
482 
     | 
    
         
             
                  else
         
     | 
| 
       385 
483 
     | 
    
         
             
                    # For whatever reason the constant that corresponds to this namespace has
         
     | 
| 
       386 
484 
     | 
    
         
             
                    # already been defined, we have to recurse.
         
     | 
| 
       387 
     | 
    
         
            -
                    log("the namespace #{ 
     | 
| 
       388 
     | 
    
         
            -
                     
     | 
| 
      
 485 
     | 
    
         
            +
                    log("the namespace #{cref.path} already exists, descending into #{subdir}") if logger
         
     | 
| 
      
 486 
     | 
    
         
            +
                    define_autoloads_for_dir(subdir, cref.get)
         
     | 
| 
       389 
487 
     | 
    
         
             
                  end
         
     | 
| 
       390 
488 
     | 
    
         
             
                end
         
     | 
| 
       391 
489 
     | 
    
         | 
| 
       392 
490 
     | 
    
         
             
                # @sig (Module, Symbol, String) -> void
         
     | 
| 
       393 
     | 
    
         
            -
                private def autoload_file( 
     | 
| 
       394 
     | 
    
         
            -
                  if autoload_path =  
     | 
| 
      
 491 
     | 
    
         
            +
                private def autoload_file(cref, file)
         
     | 
| 
      
 492 
     | 
    
         
            +
                  if autoload_path = cref.autoload? || Registry.inception?(cref.path)
         
     | 
| 
       395 
493 
     | 
    
         
             
                    # First autoload for a Ruby file wins, just ignore subsequent ones.
         
     | 
| 
       396 
494 
     | 
    
         
             
                    if ruby?(autoload_path)
         
     | 
| 
       397 
495 
     | 
    
         
             
                      shadowed_files << file
         
     | 
| 
       398 
496 
     | 
    
         
             
                      log("file #{file} is ignored because #{autoload_path} has precedence") if logger
         
     | 
| 
       399 
497 
     | 
    
         
             
                    else
         
     | 
| 
       400 
     | 
    
         
            -
                      promote_namespace_from_implicit_to_explicit(
         
     | 
| 
       401 
     | 
    
         
            -
                        dir:    autoload_path,
         
     | 
| 
       402 
     | 
    
         
            -
                        file:   file,
         
     | 
| 
       403 
     | 
    
         
            -
                        parent: parent,
         
     | 
| 
       404 
     | 
    
         
            -
                        cname:  cname
         
     | 
| 
       405 
     | 
    
         
            -
                      )
         
     | 
| 
      
 498 
     | 
    
         
            +
                      promote_namespace_from_implicit_to_explicit(dir: autoload_path, file: file, cref: cref)
         
     | 
| 
       406 
499 
     | 
    
         
             
                    end
         
     | 
| 
       407 
     | 
    
         
            -
                  elsif  
     | 
| 
      
 500 
     | 
    
         
            +
                  elsif cref.defined?
         
     | 
| 
       408 
501 
     | 
    
         
             
                    shadowed_files << file
         
     | 
| 
       409 
     | 
    
         
            -
                    log("file #{file} is ignored because #{ 
     | 
| 
      
 502 
     | 
    
         
            +
                    log("file #{file} is ignored because #{cref.path} is already defined") if logger
         
     | 
| 
       410 
503 
     | 
    
         
             
                  else
         
     | 
| 
       411 
     | 
    
         
            -
                     
     | 
| 
      
 504 
     | 
    
         
            +
                    define_autoload(cref, file)
         
     | 
| 
       412 
505 
     | 
    
         
             
                  end
         
     | 
| 
       413 
506 
     | 
    
         
             
                end
         
     | 
| 
       414 
507 
     | 
    
         | 
| 
       415 
508 
     | 
    
         
             
                # `dir` is the directory that would have autovivified a namespace. `file` is
         
     | 
| 
       416 
509 
     | 
    
         
             
                # the file where we've found the namespace is explicitly defined.
         
     | 
| 
       417 
510 
     | 
    
         
             
                #
         
     | 
| 
       418 
     | 
    
         
            -
                # @sig (dir: String, file: String,  
     | 
| 
       419 
     | 
    
         
            -
                private def promote_namespace_from_implicit_to_explicit(dir:, file:,  
     | 
| 
      
 511 
     | 
    
         
            +
                # @sig (dir: String, file: String, cref: Zeitwerk::Cref) -> void
         
     | 
| 
      
 512 
     | 
    
         
            +
                private def promote_namespace_from_implicit_to_explicit(dir:, file:, cref:)
         
     | 
| 
       420 
513 
     | 
    
         
             
                  autoloads.delete(dir)
         
     | 
| 
       421 
514 
     | 
    
         
             
                  Registry.unregister_autoload(dir)
         
     | 
| 
       422 
515 
     | 
    
         | 
| 
       423 
     | 
    
         
            -
                  log("earlier autoload for #{ 
     | 
| 
      
 516 
     | 
    
         
            +
                  log("earlier autoload for #{cref.path} discarded, it is actually an explicit namespace defined in #{file}") if logger
         
     | 
| 
       424 
517 
     | 
    
         | 
| 
       425 
     | 
    
         
            -
                   
     | 
| 
       426 
     | 
    
         
            -
                  register_explicit_namespace( 
     | 
| 
      
 518 
     | 
    
         
            +
                  define_autoload(cref, file)
         
     | 
| 
      
 519 
     | 
    
         
            +
                  register_explicit_namespace(cref.path)
         
     | 
| 
       427 
520 
     | 
    
         
             
                end
         
     | 
| 
       428 
521 
     | 
    
         | 
| 
       429 
522 
     | 
    
         
             
                # @sig (Module, Symbol, String) -> void
         
     | 
| 
       430 
     | 
    
         
            -
                private def  
     | 
| 
       431 
     | 
    
         
            -
                   
     | 
| 
      
 523 
     | 
    
         
            +
                private def define_autoload(cref, abspath)
         
     | 
| 
      
 524 
     | 
    
         
            +
                  cref.autoload(abspath)
         
     | 
| 
       432 
525 
     | 
    
         | 
| 
       433 
526 
     | 
    
         
             
                  if logger
         
     | 
| 
       434 
527 
     | 
    
         
             
                    if ruby?(abspath)
         
     | 
| 
       435 
     | 
    
         
            -
                      log("autoload set for #{ 
     | 
| 
      
 528 
     | 
    
         
            +
                      log("autoload set for #{cref.path}, to be loaded from #{abspath}")
         
     | 
| 
       436 
529 
     | 
    
         
             
                    else
         
     | 
| 
       437 
     | 
    
         
            -
                      log("autoload set for #{ 
     | 
| 
      
 530 
     | 
    
         
            +
                      log("autoload set for #{cref.path}, to be autovivified from #{abspath}")
         
     | 
| 
       438 
531 
     | 
    
         
             
                    end
         
     | 
| 
       439 
532 
     | 
    
         
             
                  end
         
     | 
| 
       440 
533 
     | 
    
         | 
| 
       441 
     | 
    
         
            -
                  autoloads[abspath] =  
     | 
| 
      
 534 
     | 
    
         
            +
                  autoloads[abspath] = cref
         
     | 
| 
       442 
535 
     | 
    
         
             
                  Registry.register_autoload(self, abspath)
         
     | 
| 
       443 
536 
     | 
    
         | 
| 
       444 
537 
     | 
    
         
             
                  # See why in the documentation of Zeitwerk::Registry.inceptions.
         
     | 
| 
       445 
     | 
    
         
            -
                  unless  
     | 
| 
       446 
     | 
    
         
            -
                    Registry.register_inception( 
     | 
| 
      
 538 
     | 
    
         
            +
                  unless cref.autoload?
         
     | 
| 
      
 539 
     | 
    
         
            +
                    Registry.register_inception(cref.path, abspath, self)
         
     | 
| 
       447 
540 
     | 
    
         
             
                  end
         
     | 
| 
       448 
541 
     | 
    
         
             
                end
         
     | 
| 
       449 
542 
     | 
    
         | 
| 
       450 
543 
     | 
    
         
             
                # @sig (Module, Symbol) -> String?
         
     | 
| 
       451 
     | 
    
         
            -
                private def autoload_path_set_by_me_for?( 
     | 
| 
       452 
     | 
    
         
            -
                  if autoload_path =  
     | 
| 
      
 544 
     | 
    
         
            +
                private def autoload_path_set_by_me_for?(cref)
         
     | 
| 
      
 545 
     | 
    
         
            +
                  if autoload_path = cref.autoload?
         
     | 
| 
       453 
546 
     | 
    
         
             
                    autoload_path if autoloads.key?(autoload_path)
         
     | 
| 
       454 
547 
     | 
    
         
             
                  else
         
     | 
| 
       455 
     | 
    
         
            -
                    Registry.inception?( 
     | 
| 
      
 548 
     | 
    
         
            +
                    Registry.inception?(cref.path, self)
         
     | 
| 
       456 
549 
     | 
    
         
             
                  end
         
     | 
| 
       457 
550 
     | 
    
         
             
                end
         
     | 
| 
       458 
551 
     | 
    
         | 
| 
         @@ -479,7 +572,6 @@ module Zeitwerk 
     | 
|
| 
       479 
572 
     | 
    
         
             
                          raise Error,
         
     | 
| 
       480 
573 
     | 
    
         
             
                            "loader\n\n#{pretty_inspect}\n\nwants to manage directory #{dir}," \
         
     | 
| 
       481 
574 
     | 
    
         
             
                            " which is already managed by\n\n#{loader.pretty_inspect}\n"
         
     | 
| 
       482 
     | 
    
         
            -
                          EOS
         
     | 
| 
       483 
575 
     | 
    
         
             
                        end
         
     | 
| 
       484 
576 
     | 
    
         
             
                      end
         
     | 
| 
       485 
577 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -494,21 +586,21 @@ module Zeitwerk 
     | 
|
| 
       494 
586 
     | 
    
         
             
                end
         
     | 
| 
       495 
587 
     | 
    
         | 
| 
       496 
588 
     | 
    
         
             
                # @sig (Module, Symbol) -> void
         
     | 
| 
       497 
     | 
    
         
            -
                private def unload_autoload( 
     | 
| 
       498 
     | 
    
         
            -
                   
     | 
| 
       499 
     | 
    
         
            -
                  log("autoload for #{ 
     | 
| 
      
 589 
     | 
    
         
            +
                private def unload_autoload(cref)
         
     | 
| 
      
 590 
     | 
    
         
            +
                  cref.remove
         
     | 
| 
      
 591 
     | 
    
         
            +
                  log("autoload for #{cref.path} removed") if logger
         
     | 
| 
       500 
592 
     | 
    
         
             
                end
         
     | 
| 
       501 
593 
     | 
    
         | 
| 
       502 
594 
     | 
    
         
             
                # @sig (Module, Symbol) -> void
         
     | 
| 
       503 
     | 
    
         
            -
                private def unload_cref( 
     | 
| 
      
 595 
     | 
    
         
            +
                private def unload_cref(cref)
         
     | 
| 
       504 
596 
     | 
    
         
             
                  # Let's optimistically remove_const. The way we use it, this is going to
         
     | 
| 
       505 
597 
     | 
    
         
             
                  # succeed always if all is good.
         
     | 
| 
       506 
     | 
    
         
            -
                   
     | 
| 
      
 598 
     | 
    
         
            +
                  cref.remove
         
     | 
| 
       507 
599 
     | 
    
         
             
                rescue ::NameError
         
     | 
| 
       508 
600 
     | 
    
         
             
                  # There are a few edge scenarios in which this may happen. If the constant
         
     | 
| 
       509 
601 
     | 
    
         
             
                  # is gone, that is OK, anyway.
         
     | 
| 
       510 
602 
     | 
    
         
             
                else
         
     | 
| 
       511 
     | 
    
         
            -
                  log("#{ 
     | 
| 
      
 603 
     | 
    
         
            +
                  log("#{cref.path} unloaded") if logger
         
     | 
| 
       512 
604 
     | 
    
         
             
                end
         
     | 
| 
       513 
605 
     | 
    
         
             
              end
         
     | 
| 
       514 
606 
     | 
    
         
             
            end
         
     | 
    
        data/lib/zeitwerk/registry.rb
    CHANGED
    
    | 
         @@ -86,8 +86,8 @@ module Zeitwerk 
     | 
|
| 
       86 
86 
     | 
    
         
             
                  #
         
     | 
| 
       87 
87 
     | 
    
         
             
                  # @private
         
     | 
| 
       88 
88 
     | 
    
         
             
                  # @sig (String) -> Zeitwerk::Loader
         
     | 
| 
       89 
     | 
    
         
            -
                  def loader_for_gem(root_file, warn_on_extra_files:)
         
     | 
| 
       90 
     | 
    
         
            -
                    gem_loaders_by_root_file[root_file] ||= GemLoader. 
     | 
| 
      
 89 
     | 
    
         
            +
                  def loader_for_gem(root_file, namespace:, warn_on_extra_files:)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    gem_loaders_by_root_file[root_file] ||= GemLoader.__new(root_file, namespace: namespace, warn_on_extra_files: warn_on_extra_files)
         
     | 
| 
       91 
91 
     | 
    
         
             
                  end
         
     | 
| 
       92 
92 
     | 
    
         | 
| 
       93 
93 
     | 
    
         
             
                  # @private
         
     | 
| 
         @@ -110,9 +110,12 @@ module Zeitwerk 
     | 
|
| 
       110 
110 
     | 
    
         | 
| 
       111 
111 
     | 
    
         
             
                  # @private
         
     | 
| 
       112 
112 
     | 
    
         
             
                  # @sig (String) -> String?
         
     | 
| 
       113 
     | 
    
         
            -
                  def inception?(cpath)
         
     | 
| 
      
 113 
     | 
    
         
            +
                  def inception?(cpath, registered_by_loader=nil)
         
     | 
| 
       114 
114 
     | 
    
         
             
                    if pair = inceptions[cpath]
         
     | 
| 
       115 
     | 
    
         
            -
                      pair 
     | 
| 
      
 115 
     | 
    
         
            +
                      abspath, loader = pair
         
     | 
| 
      
 116 
     | 
    
         
            +
                      if registered_by_loader.nil? || registered_by_loader.equal?(loader)
         
     | 
| 
      
 117 
     | 
    
         
            +
                        abspath
         
     | 
| 
      
 118 
     | 
    
         
            +
                      end
         
     | 
| 
       116 
119 
     | 
    
         
             
                    end
         
     | 
| 
       117 
120 
     | 
    
         
             
                  end
         
     | 
| 
       118 
121 
     | 
    
         | 
    
        data/lib/zeitwerk/version.rb
    CHANGED
    
    
    
        data/lib/zeitwerk.rb
    CHANGED
    
    | 
         @@ -3,12 +3,14 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Zeitwerk
         
     | 
| 
       4 
4 
     | 
    
         
             
              require_relative "zeitwerk/real_mod_name"
         
     | 
| 
       5 
5 
     | 
    
         
             
              require_relative "zeitwerk/internal"
         
     | 
| 
      
 6 
     | 
    
         
            +
              require_relative "zeitwerk/cref"
         
     | 
| 
       6 
7 
     | 
    
         
             
              require_relative "zeitwerk/loader"
         
     | 
| 
       7 
8 
     | 
    
         
             
              require_relative "zeitwerk/gem_loader"
         
     | 
| 
       8 
9 
     | 
    
         
             
              require_relative "zeitwerk/registry"
         
     | 
| 
       9 
10 
     | 
    
         
             
              require_relative "zeitwerk/explicit_namespace"
         
     | 
| 
       10 
11 
     | 
    
         
             
              require_relative "zeitwerk/inflector"
         
     | 
| 
       11 
12 
     | 
    
         
             
              require_relative "zeitwerk/gem_inflector"
         
     | 
| 
      
 13 
     | 
    
         
            +
              require_relative "zeitwerk/null_inflector"
         
     | 
| 
       12 
14 
     | 
    
         
             
              require_relative "zeitwerk/kernel"
         
     | 
| 
       13 
15 
     | 
    
         
             
              require_relative "zeitwerk/error"
         
     | 
| 
       14 
16 
     | 
    
         
             
              require_relative "zeitwerk/version"
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: zeitwerk
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 2.6. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 2.6.18
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Xavier Noria
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2024-09-02 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       13 
13 
     | 
    
         
             
            description: |2
         
     | 
| 
       14 
14 
     | 
    
         
             
                  Zeitwerk implements constant autoloading with Ruby semantics. Each gem
         
     | 
| 
         @@ -23,6 +23,7 @@ files: 
     | 
|
| 
       23 
23 
     | 
    
         
             
            - MIT-LICENSE
         
     | 
| 
       24 
24 
     | 
    
         
             
            - README.md
         
     | 
| 
       25 
25 
     | 
    
         
             
            - lib/zeitwerk.rb
         
     | 
| 
      
 26 
     | 
    
         
            +
            - lib/zeitwerk/cref.rb
         
     | 
| 
       26 
27 
     | 
    
         
             
            - lib/zeitwerk/error.rb
         
     | 
| 
       27 
28 
     | 
    
         
             
            - lib/zeitwerk/explicit_namespace.rb
         
     | 
| 
       28 
29 
     | 
    
         
             
            - lib/zeitwerk/gem_inflector.rb
         
     | 
| 
         @@ -35,6 +36,7 @@ files: 
     | 
|
| 
       35 
36 
     | 
    
         
             
            - lib/zeitwerk/loader/config.rb
         
     | 
| 
       36 
37 
     | 
    
         
             
            - lib/zeitwerk/loader/eager_load.rb
         
     | 
| 
       37 
38 
     | 
    
         
             
            - lib/zeitwerk/loader/helpers.rb
         
     | 
| 
      
 39 
     | 
    
         
            +
            - lib/zeitwerk/null_inflector.rb
         
     | 
| 
       38 
40 
     | 
    
         
             
            - lib/zeitwerk/real_mod_name.rb
         
     | 
| 
       39 
41 
     | 
    
         
             
            - lib/zeitwerk/registry.rb
         
     | 
| 
       40 
42 
     | 
    
         
             
            - lib/zeitwerk/version.rb
         
     | 
| 
         @@ -61,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       61 
63 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       62 
64 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       63 
65 
     | 
    
         
             
            requirements: []
         
     | 
| 
       64 
     | 
    
         
            -
            rubygems_version: 3. 
     | 
| 
      
 66 
     | 
    
         
            +
            rubygems_version: 3.5.11
         
     | 
| 
       65 
67 
     | 
    
         
             
            signing_key:
         
     | 
| 
       66 
68 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       67 
69 
     | 
    
         
             
            summary: Efficient and thread-safe constant autoloader
         
     |