zeitwerk 2.6.2 → 2.6.10
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 +177 -45
- data/lib/zeitwerk/error.rb +6 -0
- data/lib/zeitwerk/explicit_namespace.rb +14 -10
- data/lib/zeitwerk/gem_inflector.rb +2 -2
- data/lib/zeitwerk/gem_loader.rb +11 -7
- data/lib/zeitwerk/internal.rb +12 -0
- data/lib/zeitwerk/loader/callbacks.rb +6 -6
- data/lib/zeitwerk/loader/config.rb +68 -49
- data/lib/zeitwerk/loader/eager_load.rb +30 -18
- data/lib/zeitwerk/loader/helpers.rb +65 -17
- data/lib/zeitwerk/loader.rb +157 -73
- data/lib/zeitwerk/registry.rb +2 -2
- data/lib/zeitwerk/version.rb +1 -1
- data/lib/zeitwerk.rb +1 -0
- metadata +4 -3
data/lib/zeitwerk/loader.rb
CHANGED
|
@@ -9,6 +9,8 @@ module Zeitwerk
|
|
|
9
9
|
require_relative "loader/config"
|
|
10
10
|
require_relative "loader/eager_load"
|
|
11
11
|
|
|
12
|
+
extend Internal
|
|
13
|
+
|
|
12
14
|
include RealModName
|
|
13
15
|
include Callbacks
|
|
14
16
|
include Helpers
|
|
@@ -26,9 +28,9 @@ module Zeitwerk
|
|
|
26
28
|
# "/Users/fxn/blog/app/models/hotel/pricing.rb" => [Hotel, :Pricing]
|
|
27
29
|
# ...
|
|
28
30
|
#
|
|
29
|
-
# @private
|
|
30
31
|
# @sig Hash[String, [Module, Symbol]]
|
|
31
32
|
attr_reader :autoloads
|
|
33
|
+
internal :autoloads
|
|
32
34
|
|
|
33
35
|
# We keep track of autoloaded directories to remove them from the registry
|
|
34
36
|
# at the end of eager loading.
|
|
@@ -36,9 +38,9 @@ module Zeitwerk
|
|
|
36
38
|
# Files are removed as they are autoloaded, but directories need to wait due
|
|
37
39
|
# to concurrency (see why in Zeitwerk::Loader::Callbacks#on_dir_autoloaded).
|
|
38
40
|
#
|
|
39
|
-
# @private
|
|
40
41
|
# @sig Array[String]
|
|
41
42
|
attr_reader :autoloaded_dirs
|
|
43
|
+
internal :autoloaded_dirs
|
|
42
44
|
|
|
43
45
|
# Stores metadata needed for unloading. Its entries look like this:
|
|
44
46
|
#
|
|
@@ -52,9 +54,9 @@ module Zeitwerk
|
|
|
52
54
|
# If reloading is enabled, this hash is filled as constants are autoloaded
|
|
53
55
|
# or eager loaded. Otherwise, the collection remains empty.
|
|
54
56
|
#
|
|
55
|
-
# @private
|
|
56
57
|
# @sig Hash[String, [String, [Module, Symbol]]]
|
|
57
58
|
attr_reader :to_unload
|
|
59
|
+
internal :to_unload
|
|
58
60
|
|
|
59
61
|
# Maps namespace constant paths to their respective directories.
|
|
60
62
|
#
|
|
@@ -70,9 +72,9 @@ module Zeitwerk
|
|
|
70
72
|
# and that its children are spread over those directories. We'll visit them
|
|
71
73
|
# to set up the corresponding autoloads.
|
|
72
74
|
#
|
|
73
|
-
# @private
|
|
74
75
|
# @sig Hash[String, Array[String]]
|
|
75
76
|
attr_reader :namespace_dirs
|
|
77
|
+
internal :namespace_dirs
|
|
76
78
|
|
|
77
79
|
# A shadowed file is a file managed by this loader that is ignored when
|
|
78
80
|
# setting autoloads because its matching constant is already taken.
|
|
@@ -81,17 +83,17 @@ module Zeitwerk
|
|
|
81
83
|
# has only scanned the top-level, `shadowed_files` does not have shadowed
|
|
82
84
|
# files that may exist deep in the project tree yet.
|
|
83
85
|
#
|
|
84
|
-
# @private
|
|
85
86
|
# @sig Set[String]
|
|
86
87
|
attr_reader :shadowed_files
|
|
88
|
+
internal :shadowed_files
|
|
87
89
|
|
|
88
|
-
# @private
|
|
89
90
|
# @sig Mutex
|
|
90
91
|
attr_reader :mutex
|
|
92
|
+
private :mutex
|
|
91
93
|
|
|
92
|
-
# @private
|
|
93
94
|
# @sig Mutex
|
|
94
95
|
attr_reader :mutex2
|
|
96
|
+
private :mutex2
|
|
95
97
|
|
|
96
98
|
def initialize
|
|
97
99
|
super
|
|
@@ -109,15 +111,15 @@ module Zeitwerk
|
|
|
109
111
|
Registry.register_loader(self)
|
|
110
112
|
end
|
|
111
113
|
|
|
112
|
-
# Sets autoloads in the root
|
|
114
|
+
# Sets autoloads in the root namespaces.
|
|
113
115
|
#
|
|
114
116
|
# @sig () -> void
|
|
115
117
|
def setup
|
|
116
118
|
mutex.synchronize do
|
|
117
119
|
break if @setup
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
set_autoloads_in_dir(root_dir,
|
|
121
|
+
actual_roots.each do |root_dir, root_namespace|
|
|
122
|
+
set_autoloads_in_dir(root_dir, root_namespace)
|
|
121
123
|
end
|
|
122
124
|
|
|
123
125
|
on_setup_callbacks.each(&:call)
|
|
@@ -134,12 +136,14 @@ module Zeitwerk
|
|
|
134
136
|
# unload them.
|
|
135
137
|
#
|
|
136
138
|
# This method is public but undocumented. Main interface is `reload`, which
|
|
137
|
-
# means `unload` + `setup`. This one is
|
|
139
|
+
# means `unload` + `setup`. This one is available to be used together with
|
|
138
140
|
# `unregister`, which is undocumented too.
|
|
139
141
|
#
|
|
140
142
|
# @sig () -> void
|
|
141
143
|
def unload
|
|
142
144
|
mutex.synchronize do
|
|
145
|
+
raise SetupRequired unless @setup
|
|
146
|
+
|
|
143
147
|
# We are going to keep track of the files that were required by our
|
|
144
148
|
# autoloads to later remove them from $LOADED_FEATURES, thus making them
|
|
145
149
|
# loadable by Kernel#require again.
|
|
@@ -199,7 +203,7 @@ module Zeitwerk
|
|
|
199
203
|
shadowed_files.clear
|
|
200
204
|
|
|
201
205
|
Registry.on_unload(self)
|
|
202
|
-
ExplicitNamespace.
|
|
206
|
+
ExplicitNamespace.__unregister_loader(self)
|
|
203
207
|
|
|
204
208
|
@setup = false
|
|
205
209
|
@eager_loaded = false
|
|
@@ -216,6 +220,7 @@ module Zeitwerk
|
|
|
216
220
|
# @sig () -> void
|
|
217
221
|
def reload
|
|
218
222
|
raise ReloadingDisabledError unless reloading_enabled?
|
|
223
|
+
raise SetupRequired unless @setup
|
|
219
224
|
|
|
220
225
|
unload
|
|
221
226
|
recompute_ignored_paths
|
|
@@ -223,6 +228,54 @@ module Zeitwerk
|
|
|
223
228
|
setup
|
|
224
229
|
end
|
|
225
230
|
|
|
231
|
+
# @sig (String | Pathname) -> String?
|
|
232
|
+
def cpath_expected_at(path)
|
|
233
|
+
abspath = File.expand_path(path)
|
|
234
|
+
|
|
235
|
+
raise Zeitwerk::Error.new("#{abspath} does not exist") unless File.exist?(abspath)
|
|
236
|
+
|
|
237
|
+
return unless dir?(abspath) || ruby?(abspath)
|
|
238
|
+
return if ignored_path?(abspath)
|
|
239
|
+
|
|
240
|
+
paths = []
|
|
241
|
+
|
|
242
|
+
if ruby?(abspath)
|
|
243
|
+
basename = File.basename(abspath, ".rb")
|
|
244
|
+
return if hidden?(basename)
|
|
245
|
+
|
|
246
|
+
paths << [basename, abspath]
|
|
247
|
+
walk_up_from = File.dirname(abspath)
|
|
248
|
+
else
|
|
249
|
+
walk_up_from = abspath
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
root_namespace = nil
|
|
253
|
+
|
|
254
|
+
walk_up(walk_up_from) do |dir|
|
|
255
|
+
break if root_namespace = roots[dir]
|
|
256
|
+
return if ignored_path?(dir)
|
|
257
|
+
|
|
258
|
+
basename = File.basename(dir)
|
|
259
|
+
return if hidden?(basename)
|
|
260
|
+
|
|
261
|
+
paths << [basename, abspath] unless collapse?(dir)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
return unless root_namespace
|
|
265
|
+
|
|
266
|
+
if paths.empty?
|
|
267
|
+
real_mod_name(root_namespace)
|
|
268
|
+
else
|
|
269
|
+
cnames = paths.reverse_each.map { |b, a| cname_for(b, a) }
|
|
270
|
+
|
|
271
|
+
if root_namespace == Object
|
|
272
|
+
cnames.join("::")
|
|
273
|
+
else
|
|
274
|
+
"#{real_mod_name(root_namespace)}::#{cnames.join("::")}"
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
226
279
|
# Says if the given constant path would be unloaded on reload. This
|
|
227
280
|
# predicate returns `false` if reloading is disabled.
|
|
228
281
|
#
|
|
@@ -245,27 +298,29 @@ module Zeitwerk
|
|
|
245
298
|
# @sig () -> void
|
|
246
299
|
def unregister
|
|
247
300
|
Registry.unregister_loader(self)
|
|
248
|
-
ExplicitNamespace.
|
|
301
|
+
ExplicitNamespace.__unregister_loader(self)
|
|
249
302
|
end
|
|
250
303
|
|
|
251
304
|
# The return value of this predicate is only meaningful if the loader has
|
|
252
305
|
# scanned the file. This is the case in the spots where we use it.
|
|
253
306
|
#
|
|
254
|
-
# @private
|
|
255
307
|
# @sig (String) -> Boolean
|
|
256
|
-
def shadowed_file?(file)
|
|
308
|
+
internal def shadowed_file?(file)
|
|
257
309
|
shadowed_files.member?(file)
|
|
258
310
|
end
|
|
259
311
|
|
|
260
312
|
# --- Class methods ---------------------------------------------------------------------------
|
|
261
313
|
|
|
262
314
|
class << self
|
|
315
|
+
include RealModName
|
|
316
|
+
|
|
263
317
|
# @sig #call | #debug | nil
|
|
264
318
|
attr_accessor :default_logger
|
|
265
319
|
|
|
266
320
|
# This is a shortcut for
|
|
267
321
|
#
|
|
268
322
|
# require "zeitwerk"
|
|
323
|
+
#
|
|
269
324
|
# loader = Zeitwerk::Loader.new
|
|
270
325
|
# loader.tag = File.basename(__FILE__, ".rb")
|
|
271
326
|
# loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
|
|
@@ -280,22 +335,63 @@ module Zeitwerk
|
|
|
280
335
|
# @sig (bool) -> Zeitwerk::GemLoader
|
|
281
336
|
def for_gem(warn_on_extra_files: true)
|
|
282
337
|
called_from = caller_locations(1, 1).first.path
|
|
283
|
-
Registry.loader_for_gem(called_from, warn_on_extra_files: warn_on_extra_files)
|
|
338
|
+
Registry.loader_for_gem(called_from, namespace: Object, warn_on_extra_files: warn_on_extra_files)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# This is a shortcut for
|
|
342
|
+
#
|
|
343
|
+
# require "zeitwerk"
|
|
344
|
+
#
|
|
345
|
+
# loader = Zeitwerk::Loader.new
|
|
346
|
+
# loader.tag = namespace.name + "-" + File.basename(__FILE__, ".rb")
|
|
347
|
+
# loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
|
|
348
|
+
# loader.push_dir(__dir__, namespace: namespace)
|
|
349
|
+
#
|
|
350
|
+
# except that this method returns the same object in subsequent calls from
|
|
351
|
+
# the same file, in the unlikely case the gem wants to be able to reload.
|
|
352
|
+
#
|
|
353
|
+
# This method returns a subclass of Zeitwerk::Loader, but the exact type
|
|
354
|
+
# is private, client code can only rely on the interface.
|
|
355
|
+
#
|
|
356
|
+
# @sig (bool) -> Zeitwerk::GemLoader
|
|
357
|
+
def for_gem_extension(namespace)
|
|
358
|
+
unless namespace.is_a?(Module) # Note that Class < Module.
|
|
359
|
+
raise Zeitwerk::Error, "#{namespace.inspect} is not a class or module object, should be"
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
unless real_mod_name(namespace)
|
|
363
|
+
raise Zeitwerk::Error, "extending anonymous namespaces is unsupported"
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
called_from = caller_locations(1, 1).first.path
|
|
367
|
+
Registry.loader_for_gem(called_from, namespace: namespace, warn_on_extra_files: false)
|
|
284
368
|
end
|
|
285
369
|
|
|
286
|
-
# Broadcasts `eager_load` to all loaders.
|
|
370
|
+
# Broadcasts `eager_load` to all loaders. Those that have not been setup
|
|
371
|
+
# are skipped.
|
|
287
372
|
#
|
|
288
373
|
# @sig () -> void
|
|
289
374
|
def eager_load_all
|
|
290
|
-
Registry.loaders.each
|
|
375
|
+
Registry.loaders.each do |loader|
|
|
376
|
+
begin
|
|
377
|
+
loader.eager_load
|
|
378
|
+
rescue SetupRequired
|
|
379
|
+
# This is fine, we eager load what can be eager loaded.
|
|
380
|
+
end
|
|
381
|
+
end
|
|
291
382
|
end
|
|
292
383
|
|
|
293
|
-
# Broadcasts `eager_load_namespace` to all loaders.
|
|
384
|
+
# Broadcasts `eager_load_namespace` to all loaders. Those that have not
|
|
385
|
+
# been setup are skipped.
|
|
294
386
|
#
|
|
295
387
|
# @sig (Module) -> void
|
|
296
388
|
def eager_load_namespace(mod)
|
|
297
389
|
Registry.loaders.each do |loader|
|
|
298
|
-
|
|
390
|
+
begin
|
|
391
|
+
loader.eager_load_namespace(mod)
|
|
392
|
+
rescue SetupRequired
|
|
393
|
+
# This is fine, we eager load what can be eager loaded.
|
|
394
|
+
end
|
|
299
395
|
end
|
|
300
396
|
end
|
|
301
397
|
|
|
@@ -308,51 +404,39 @@ module Zeitwerk
|
|
|
308
404
|
end
|
|
309
405
|
end
|
|
310
406
|
|
|
311
|
-
private # -------------------------------------------------------------------------------------
|
|
312
|
-
|
|
313
407
|
# @sig (String, Module) -> void
|
|
314
|
-
def set_autoloads_in_dir(dir, parent)
|
|
408
|
+
private def set_autoloads_in_dir(dir, parent)
|
|
315
409
|
ls(dir) do |basename, abspath|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
410
|
+
if ruby?(basename)
|
|
411
|
+
basename.delete_suffix!(".rb")
|
|
412
|
+
autoload_file(parent, cname_for(basename, abspath), abspath)
|
|
413
|
+
else
|
|
414
|
+
if collapse?(abspath)
|
|
415
|
+
set_autoloads_in_dir(abspath, parent)
|
|
321
416
|
else
|
|
322
|
-
|
|
323
|
-
set_autoloads_in_dir(abspath, parent)
|
|
324
|
-
else
|
|
325
|
-
cname = inflector.camelize(basename, abspath).to_sym
|
|
326
|
-
autoload_subdir(parent, cname, abspath)
|
|
327
|
-
end
|
|
417
|
+
autoload_subdir(parent, cname_for(basename, abspath), abspath)
|
|
328
418
|
end
|
|
329
|
-
rescue ::NameError => error
|
|
330
|
-
path_type = ruby?(abspath) ? "file" : "directory"
|
|
331
|
-
|
|
332
|
-
raise NameError.new(<<~MESSAGE, error.name)
|
|
333
|
-
#{error.message} inferred by #{inflector.class} from #{path_type}
|
|
334
|
-
|
|
335
|
-
#{abspath}
|
|
336
|
-
|
|
337
|
-
Possible ways to address this:
|
|
338
|
-
|
|
339
|
-
* Tell Zeitwerk to ignore this particular #{path_type}.
|
|
340
|
-
* Tell Zeitwerk to ignore one of its parent directories.
|
|
341
|
-
* Rename the #{path_type} to comply with the naming conventions.
|
|
342
|
-
* Modify the inflector to handle this case.
|
|
343
|
-
MESSAGE
|
|
344
419
|
end
|
|
345
420
|
end
|
|
346
421
|
end
|
|
347
422
|
|
|
348
423
|
# @sig (Module, Symbol, String) -> void
|
|
349
|
-
def autoload_subdir(parent, cname, subdir)
|
|
424
|
+
private def autoload_subdir(parent, cname, subdir)
|
|
350
425
|
if autoload_path = autoload_path_set_by_me_for?(parent, cname)
|
|
351
426
|
cpath = cpath(parent, cname)
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
427
|
+
if ruby?(autoload_path)
|
|
428
|
+
# Scanning visited a Ruby file first, and now a directory for the same
|
|
429
|
+
# constant has been found. This means we are dealing with an explicit
|
|
430
|
+
# namespace whose definition was seen first.
|
|
431
|
+
#
|
|
432
|
+
# Registering is idempotent, and we have to keep the autoload pointing
|
|
433
|
+
# to the file. This may run again if more directories are found later
|
|
434
|
+
# on, no big deal.
|
|
435
|
+
register_explicit_namespace(cpath)
|
|
436
|
+
end
|
|
437
|
+
# If the existing autoload points to a file, it has to be preserved, if
|
|
438
|
+
# not, it is fine as it is. In either case, we do not need to override.
|
|
439
|
+
# Just remember the subdirectory conforms this namespace.
|
|
356
440
|
namespace_dirs[cpath] << subdir
|
|
357
441
|
elsif !cdef?(parent, cname)
|
|
358
442
|
# First time we find this namespace, set an autoload for it.
|
|
@@ -367,7 +451,7 @@ module Zeitwerk
|
|
|
367
451
|
end
|
|
368
452
|
|
|
369
453
|
# @sig (Module, Symbol, String) -> void
|
|
370
|
-
def autoload_file(parent, cname, file)
|
|
454
|
+
private def autoload_file(parent, cname, file)
|
|
371
455
|
if autoload_path = strict_autoload_path(parent, cname) || Registry.inception?(cpath(parent, cname))
|
|
372
456
|
# First autoload for a Ruby file wins, just ignore subsequent ones.
|
|
373
457
|
if ruby?(autoload_path)
|
|
@@ -393,7 +477,7 @@ module Zeitwerk
|
|
|
393
477
|
# the file where we've found the namespace is explicitly defined.
|
|
394
478
|
#
|
|
395
479
|
# @sig (dir: String, file: String, parent: Module, cname: Symbol) -> void
|
|
396
|
-
def promote_namespace_from_implicit_to_explicit(dir:, file:, parent:, cname:)
|
|
480
|
+
private def promote_namespace_from_implicit_to_explicit(dir:, file:, parent:, cname:)
|
|
397
481
|
autoloads.delete(dir)
|
|
398
482
|
Registry.unregister_autoload(dir)
|
|
399
483
|
|
|
@@ -404,7 +488,7 @@ module Zeitwerk
|
|
|
404
488
|
end
|
|
405
489
|
|
|
406
490
|
# @sig (Module, Symbol, String) -> void
|
|
407
|
-
def set_autoload(parent, cname, abspath)
|
|
491
|
+
private def set_autoload(parent, cname, abspath)
|
|
408
492
|
parent.autoload(cname, abspath)
|
|
409
493
|
|
|
410
494
|
if logger
|
|
@@ -425,7 +509,7 @@ module Zeitwerk
|
|
|
425
509
|
end
|
|
426
510
|
|
|
427
511
|
# @sig (Module, Symbol) -> String?
|
|
428
|
-
def autoload_path_set_by_me_for?(parent, cname)
|
|
512
|
+
private def autoload_path_set_by_me_for?(parent, cname)
|
|
429
513
|
if autoload_path = strict_autoload_path(parent, cname)
|
|
430
514
|
autoload_path if autoloads.key?(autoload_path)
|
|
431
515
|
else
|
|
@@ -434,28 +518,28 @@ module Zeitwerk
|
|
|
434
518
|
end
|
|
435
519
|
|
|
436
520
|
# @sig (String) -> void
|
|
437
|
-
def register_explicit_namespace(cpath)
|
|
438
|
-
ExplicitNamespace.
|
|
521
|
+
private def register_explicit_namespace(cpath)
|
|
522
|
+
ExplicitNamespace.__register(cpath, self)
|
|
439
523
|
end
|
|
440
524
|
|
|
441
525
|
# @sig (String) -> void
|
|
442
|
-
def raise_if_conflicting_directory(dir)
|
|
526
|
+
private def raise_if_conflicting_directory(dir)
|
|
443
527
|
MUTEX.synchronize do
|
|
528
|
+
dir_slash = dir + "/"
|
|
529
|
+
|
|
444
530
|
Registry.loaders.each do |loader|
|
|
445
531
|
next if loader == self
|
|
446
|
-
next if loader.
|
|
532
|
+
next if loader.__ignores?(dir)
|
|
447
533
|
|
|
448
|
-
|
|
449
|
-
loader.root_dirs.each do |root_dir, _namespace|
|
|
534
|
+
loader.__roots.each_key do |root_dir|
|
|
450
535
|
next if ignores?(root_dir)
|
|
451
536
|
|
|
452
|
-
|
|
453
|
-
if
|
|
537
|
+
root_dir_slash = root_dir + "/"
|
|
538
|
+
if dir_slash.start_with?(root_dir_slash) || root_dir_slash.start_with?(dir_slash)
|
|
454
539
|
require "pp" # Needed for pretty_inspect, even in Ruby 2.5.
|
|
455
540
|
raise Error,
|
|
456
|
-
"loader\n\n#{pretty_inspect}\n\nwants to manage directory #{dir
|
|
541
|
+
"loader\n\n#{pretty_inspect}\n\nwants to manage directory #{dir}," \
|
|
457
542
|
" which is already managed by\n\n#{loader.pretty_inspect}\n"
|
|
458
|
-
EOS
|
|
459
543
|
end
|
|
460
544
|
end
|
|
461
545
|
end
|
|
@@ -463,23 +547,23 @@ module Zeitwerk
|
|
|
463
547
|
end
|
|
464
548
|
|
|
465
549
|
# @sig (String, Object, String) -> void
|
|
466
|
-
def run_on_unload_callbacks(cpath, value, abspath)
|
|
550
|
+
private def run_on_unload_callbacks(cpath, value, abspath)
|
|
467
551
|
# Order matters. If present, run the most specific one.
|
|
468
552
|
on_unload_callbacks[cpath]&.each { |c| c.call(value, abspath) }
|
|
469
553
|
on_unload_callbacks[:ANY]&.each { |c| c.call(cpath, value, abspath) }
|
|
470
554
|
end
|
|
471
555
|
|
|
472
556
|
# @sig (Module, Symbol) -> void
|
|
473
|
-
def unload_autoload(parent, cname)
|
|
474
|
-
parent
|
|
557
|
+
private def unload_autoload(parent, cname)
|
|
558
|
+
crem(parent, cname)
|
|
475
559
|
log("autoload for #{cpath(parent, cname)} removed") if logger
|
|
476
560
|
end
|
|
477
561
|
|
|
478
562
|
# @sig (Module, Symbol) -> void
|
|
479
|
-
def unload_cref(parent, cname)
|
|
563
|
+
private def unload_cref(parent, cname)
|
|
480
564
|
# Let's optimistically remove_const. The way we use it, this is going to
|
|
481
565
|
# succeed always if all is good.
|
|
482
|
-
parent
|
|
566
|
+
crem(parent, cname)
|
|
483
567
|
rescue ::NameError
|
|
484
568
|
# There are a few edge scenarios in which this may happen. If the constant
|
|
485
569
|
# is gone, that is OK, anyway.
|
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
|
data/lib/zeitwerk/version.rb
CHANGED
data/lib/zeitwerk.rb
CHANGED
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.10
|
|
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: 2023-07-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: |2
|
|
14
14
|
Zeitwerk implements constant autoloading with Ruby semantics. Each gem
|
|
@@ -28,6 +28,7 @@ files:
|
|
|
28
28
|
- lib/zeitwerk/gem_inflector.rb
|
|
29
29
|
- lib/zeitwerk/gem_loader.rb
|
|
30
30
|
- lib/zeitwerk/inflector.rb
|
|
31
|
+
- lib/zeitwerk/internal.rb
|
|
31
32
|
- lib/zeitwerk/kernel.rb
|
|
32
33
|
- lib/zeitwerk/loader.rb
|
|
33
34
|
- lib/zeitwerk/loader/callbacks.rb
|
|
@@ -60,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
60
61
|
- !ruby/object:Gem::Version
|
|
61
62
|
version: '0'
|
|
62
63
|
requirements: []
|
|
63
|
-
rubygems_version: 3.
|
|
64
|
+
rubygems_version: 3.4.16
|
|
64
65
|
signing_key:
|
|
65
66
|
specification_version: 4
|
|
66
67
|
summary: Efficient and thread-safe constant autoloader
|