zeitwerk 2.6.10 → 2.6.12

Sign up to get free protection for your applications and to get access to all the features.
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