zeitwerk 2.6.10 → 2.6.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b2955613976d014a322168f1976a93b29e388b4c72ecf5acdbb0186d212fe7c
4
- data.tar.gz: 57df7539d6fa37fcf41f1d37b6c2fa0a8db5af7af02333da35566fca92a03d8a
3
+ metadata.gz: 5a9048a5ba05f448e5406080995aab9709a3dd7c8dd32aad3aa0ba4f544b69c4
4
+ data.tar.gz: 581cf27f70c82b754a1baadf7a41f6c87c069ae2e78bd26b4ec6e02cfa2795b9
5
5
  SHA512:
6
- metadata.gz: 625ef1f9a15205afa2efea139f63b5b800660d57631fda75deccd172f72e82fb6454efe7465edb8024a9a8536b463fa523ead1582dc13aac54dfddb5535e31a9
7
- data.tar.gz: d0e0b1ff25b25ce5b9d3223fa01b3f04b4eefa7e316d55bad95686265f194aee24599e146c1ef9a05dd20dc16f670733e17e494ccd469ea9aef7e4a8b2fb973c
6
+ metadata.gz: 45327b148bab210d941ffeae022b70e5c2f2be4372f2192a08859faeed81d2cc5702b05d6e4efcf676a8fb7b451c46200ac372051c68ba84cfc31ed9339f3ede
7
+ data.tar.gz: 8e3266d7641f58b6a8f74abfa913c14ae4a79d4efd177578de4e7e144a21adc33d33279b7d2771cdc57937cfedfb1f5e193bb9e57c18ea90956b342b516e9bd9
@@ -28,10 +28,10 @@ module Kernel
28
28
  if loader = Zeitwerk::Registry.loader_for(path)
29
29
  if path.end_with?(".rb")
30
30
  required = zeitwerk_original_require(path)
31
- loader.on_file_autoloaded(path) if required
31
+ loader.__on_file_autoloaded(path) if required
32
32
  required
33
33
  else
34
- loader.on_dir_autoloaded(path)
34
+ loader.__on_dir_autoloaded(path)
35
35
  true
36
36
  end
37
37
  else
@@ -39,7 +39,7 @@ module Kernel
39
39
  if required
40
40
  abspath = $LOADED_FEATURES.last
41
41
  if loader = Zeitwerk::Registry.loader_for(abspath)
42
- loader.on_file_autoloaded(abspath)
42
+ loader.__on_file_autoloaded(abspath)
43
43
  end
44
44
  end
45
45
  required
@@ -2,12 +2,12 @@
2
2
 
3
3
  module Zeitwerk::Loader::Callbacks
4
4
  include Zeitwerk::RealModName
5
+ extend Zeitwerk::Internal
5
6
 
6
7
  # Invoked from our decorated Kernel#require when a managed file is autoloaded.
7
8
  #
8
- # @private
9
9
  # @sig (String) -> void
10
- def on_file_autoloaded(file)
10
+ internal def on_file_autoloaded(file)
11
11
  cref = autoloads.delete(file)
12
12
  cpath = cpath(*cref)
13
13
 
@@ -20,8 +20,16 @@ module Zeitwerk::Loader::Callbacks
20
20
  else
21
21
  msg = "expected file #{file} to define constant #{cpath}, but didn't"
22
22
  log(msg) if logger
23
+
24
+ # Ruby still keeps the autoload defined, but we remove it because the
25
+ # contract in Zeitwerk is more strict.
23
26
  crem(*cref)
27
+
28
+ # Since the expected constant was not defined, there is nothing to unload.
29
+ # However, if the exception is rescued and reloading is enabled, we still
30
+ # need to deleted the file from $LOADED_FEATURES.
24
31
  to_unload[cpath] = [file, cref] if reloading_enabled?
32
+
25
33
  raise Zeitwerk::NameError.new(msg, cref.last)
26
34
  end
27
35
  end
@@ -29,11 +37,11 @@ module Zeitwerk::Loader::Callbacks
29
37
  # Invoked from our decorated Kernel#require when a managed directory is
30
38
  # autoloaded.
31
39
  #
32
- # @private
33
40
  # @sig (String) -> void
34
- def on_dir_autoloaded(dir)
35
- # Module#autoload does not serialize concurrent requires, and we handle
36
- # directories ourselves, so the callback needs to account for concurrency.
41
+ internal def on_dir_autoloaded(dir)
42
+ # Module#autoload does not serialize concurrent requires in CRuby < 3.2, and
43
+ # we handle directories ourselves without going through Kernel#require, so
44
+ # the callback needs to account for concurrency.
37
45
  #
38
46
  # Multi-threading would introduce a race condition here in which thread t1
39
47
  # autovivifies the module, and while autoloads for its children are being
@@ -43,7 +51,7 @@ module Zeitwerk::Loader::Callbacks
43
51
  # That not only would reassign the constant (undesirable per se) but, worse,
44
52
  # the module object created by t2 wouldn't have any of the autoloads for its
45
53
  # children, since t1 would have correctly deleted its namespace_dirs entry.
46
- mutex2.synchronize do
54
+ dirs_autoload_monitor.synchronize do
47
55
  if cref = autoloads.delete(dir)
48
56
  autovivified_module = cref[0].const_set(cref[1], Module.new)
49
57
  cpath = autovivified_module.name
@@ -73,7 +81,7 @@ module Zeitwerk::Loader::Callbacks
73
81
  def on_namespace_loaded(namespace)
74
82
  if dirs = namespace_dirs.delete(real_mod_name(namespace))
75
83
  dirs.each do |dir|
76
- set_autoloads_in_dir(dir, namespace)
84
+ define_autoloads_for_dir(dir, namespace)
77
85
  end
78
86
  end
79
87
  end
@@ -171,7 +171,7 @@ module Zeitwerk::Loader::EagerLoad
171
171
  next if honour_exclusions && eager_load_exclusions.member?(abspath)
172
172
 
173
173
  if ruby?(abspath)
174
- if (cref = autoloads[abspath]) && !shadowed_file?(abspath)
174
+ if (cref = autoloads[abspath])
175
175
  cget(*cref)
176
176
  end
177
177
  else
@@ -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
@@ -91,9 +92,9 @@ module Zeitwerk
91
92
  attr_reader :mutex
92
93
  private :mutex
93
94
 
94
- # @sig Mutex
95
- attr_reader :mutex2
96
- private :mutex2
95
+ # @sig Monitor
96
+ attr_reader :dirs_autoload_monitor
97
+ private :dirs_autoload_monitor
97
98
 
98
99
  def initialize
99
100
  super
@@ -103,11 +104,12 @@ module Zeitwerk
103
104
  @to_unload = {}
104
105
  @namespace_dirs = Hash.new { |h, cpath| h[cpath] = [] }
105
106
  @shadowed_files = Set.new
106
- @mutex = Mutex.new
107
- @mutex2 = Mutex.new
108
107
  @setup = false
109
108
  @eager_loaded = false
110
109
 
110
+ @mutex = Mutex.new
111
+ @dirs_autoload_monitor = Monitor.new
112
+
111
113
  Registry.register_loader(self)
112
114
  end
113
115
 
@@ -119,7 +121,7 @@ module Zeitwerk
119
121
  break if @setup
120
122
 
121
123
  actual_roots.each do |root_dir, root_namespace|
122
- set_autoloads_in_dir(root_dir, root_namespace)
124
+ define_autoloads_for_dir(root_dir, root_namespace)
123
125
  end
124
126
 
125
127
  on_setup_callbacks.each(&:call)
@@ -405,14 +407,14 @@ module Zeitwerk
405
407
  end
406
408
 
407
409
  # @sig (String, Module) -> void
408
- private def set_autoloads_in_dir(dir, parent)
410
+ private def define_autoloads_for_dir(dir, parent)
409
411
  ls(dir) do |basename, abspath|
410
412
  if ruby?(basename)
411
413
  basename.delete_suffix!(".rb")
412
414
  autoload_file(parent, cname_for(basename, abspath), abspath)
413
415
  else
414
416
  if collapse?(abspath)
415
- set_autoloads_in_dir(abspath, parent)
417
+ define_autoloads_for_dir(abspath, parent)
416
418
  else
417
419
  autoload_subdir(parent, cname_for(basename, abspath), abspath)
418
420
  end
@@ -441,12 +443,12 @@ module Zeitwerk
441
443
  elsif !cdef?(parent, cname)
442
444
  # First time we find this namespace, set an autoload for it.
443
445
  namespace_dirs[cpath(parent, cname)] << subdir
444
- set_autoload(parent, cname, subdir)
446
+ define_autoload(parent, cname, subdir)
445
447
  else
446
448
  # For whatever reason the constant that corresponds to this namespace has
447
449
  # already been defined, we have to recurse.
448
450
  log("the namespace #{cpath(parent, cname)} already exists, descending into #{subdir}") if logger
449
- set_autoloads_in_dir(subdir, cget(parent, cname))
451
+ define_autoloads_for_dir(subdir, cget(parent, cname))
450
452
  end
451
453
  end
452
454
 
@@ -469,7 +471,7 @@ module Zeitwerk
469
471
  shadowed_files << file
470
472
  log("file #{file} is ignored because #{cpath(parent, cname)} is already defined") if logger
471
473
  else
472
- set_autoload(parent, cname, file)
474
+ define_autoload(parent, cname, file)
473
475
  end
474
476
  end
475
477
 
@@ -483,12 +485,12 @@ module Zeitwerk
483
485
 
484
486
  log("earlier autoload for #{cpath(parent, cname)} discarded, it is actually an explicit namespace defined in #{file}") if logger
485
487
 
486
- set_autoload(parent, cname, file)
488
+ define_autoload(parent, cname, file)
487
489
  register_explicit_namespace(cpath(parent, cname))
488
490
  end
489
491
 
490
492
  # @sig (Module, Symbol, String) -> void
491
- private def set_autoload(parent, cname, abspath)
493
+ private def define_autoload(parent, cname, abspath)
492
494
  parent.autoload(cname, abspath)
493
495
 
494
496
  if logger
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zeitwerk
4
- VERSION = "2.6.10"
4
+ VERSION = "2.6.12"
5
5
  end
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.10
4
+ version: 2.6.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xavier Noria
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-30 00:00:00.000000000 Z
11
+ date: 2023-09-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  Zeitwerk implements constant autoloading with Ruby semantics. Each gem