zeitwerk 2.5.0.beta6 → 2.5.3
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 +20 -8
- data/lib/zeitwerk/kernel.rb +9 -9
- data/lib/zeitwerk/loader.rb +22 -19
- data/lib/zeitwerk/version.rb +1 -1
- data/lib/zeitwerk.rb +0 -1
- metadata +4 -5
- data/lib/zeitwerk/autoloads.rb +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e0d44c224600274a41893cc27d119539f5d625c3be6ed46a54052d9b139c58c
|
4
|
+
data.tar.gz: 16c701ed5717318fab08631a001a7c067f81a2027fabbfe4b6a0f6775da60a7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d897fb5bdfc8b27080dbcd6160945e4a4cec6fb0f31c4eb21cd448ec26d1291ad373696995aaddcf4e387b7d731fbe4530b43f3b77f97159ba69bed447f07ade
|
7
|
+
data.tar.gz: 3cc2dbbc0840f2d420eb32ed725aaf24b7d889d989060211a9877703b44b6e71fa1d1884df2f50cfbf121b1954cf51db7e867232cde7470698fdb7e408c1be23
|
data/README.md
CHANGED
@@ -50,8 +50,8 @@
|
|
50
50
|
- [Rules of thumb](#rules-of-thumb)
|
51
51
|
- [Debuggers](#debuggers)
|
52
52
|
- [debug.rb](#debugrb)
|
53
|
-
- [Break](#break)
|
54
53
|
- [Byebug](#byebug)
|
54
|
+
- [Break](#break)
|
55
55
|
- [Pronunciation](#pronunciation)
|
56
56
|
- [Supported Ruby versions](#supported-ruby-versions)
|
57
57
|
- [Testing](#testing)
|
@@ -810,7 +810,9 @@ Kernel.module_eval do
|
|
810
810
|
end
|
811
811
|
```
|
812
812
|
|
813
|
-
|
813
|
+
`Kernel` is already defined by Ruby so the module cannot be autoloaded. Also, that file does not define a constant path after the path name. Therefore, Zeitwerk should not process it at all.
|
814
|
+
|
815
|
+
The extension can still coexist with the rest of the project, you only need to tell Zeitwerk to ignore it:
|
814
816
|
|
815
817
|
```ruby
|
816
818
|
kernel_ext = "#{__dir__}/my_gem/core_ext/kernel.rb"
|
@@ -826,6 +828,14 @@ loader.ignore(core_ext)
|
|
826
828
|
loader.setup
|
827
829
|
```
|
828
830
|
|
831
|
+
Now, that file has to be loaded manually with `require` or `require_relative`:
|
832
|
+
|
833
|
+
```ruby
|
834
|
+
require_relative "my_gem/core_ext/kernel"
|
835
|
+
```
|
836
|
+
|
837
|
+
and you can do that anytime, before configuring the loader, or after configuring the loader, does not matter.
|
838
|
+
|
829
839
|
<a id="markdown-use-case-the-adapter-pattern" name="use-case-the-adapter-pattern"></a>
|
830
840
|
#### Use case: The adapter pattern
|
831
841
|
|
@@ -973,17 +983,19 @@ With that, when Zeitwerk scans the file system and reaches the gem directories `
|
|
973
983
|
<a id="markdown-debugrb" name="debugrb"></a>
|
974
984
|
#### debug.rb
|
975
985
|
|
976
|
-
The new [debug.rb](https://github.com/ruby/debug) gem and Zeitwerk
|
986
|
+
The new [debug.rb](https://github.com/ruby/debug) gem and Zeitwerk are mostly compatible. This is the new debugger that is going to ship with Ruby 3.1.
|
977
987
|
|
978
|
-
|
979
|
-
#### Break
|
980
|
-
|
981
|
-
Zeitwerk works fine with [@gsamokovarov](https://github.com/gsamokovarov)'s [Break](https://github.com/gsamokovarov/break) debugger.
|
988
|
+
There's one exception, though: Due to a technical limitation of tracepoints, explicit namespaces are not autoloaded while expressions are evaluated in the REPL. See [ruby/debug#408](https://github.com/ruby/debug/issues/408).
|
982
989
|
|
983
990
|
<a id="markdown-byebug" name="byebug"></a>
|
984
991
|
#### Byebug
|
985
992
|
|
986
|
-
Zeitwerk and [Byebug](https://github.com/deivid-rodriguez/byebug)
|
993
|
+
Zeitwerk and [Byebug](https://github.com/deivid-rodriguez/byebug) have a similar edge incompatibility.
|
994
|
+
|
995
|
+
<a id="markdown-break" name="break"></a>
|
996
|
+
#### Break
|
997
|
+
|
998
|
+
Zeitwerk works fine with [@gsamokovarov](https://github.com/gsamokovarov)'s [Break](https://github.com/gsamokovarov/break) debugger.
|
987
999
|
|
988
1000
|
<a id="markdown-pronunciation" name="pronunciation"></a>
|
989
1001
|
## Pronunciation
|
data/lib/zeitwerk/kernel.rb
CHANGED
@@ -24,22 +24,22 @@ module Kernel
|
|
24
24
|
def require(path)
|
25
25
|
if loader = Zeitwerk::Registry.loader_for(path)
|
26
26
|
if path.end_with?(".rb")
|
27
|
-
zeitwerk_original_require(path)
|
28
|
-
|
29
|
-
|
27
|
+
required = zeitwerk_original_require(path)
|
28
|
+
loader.on_file_autoloaded(path) if required
|
29
|
+
required
|
30
30
|
else
|
31
31
|
loader.on_dir_autoloaded(path)
|
32
32
|
true
|
33
33
|
end
|
34
34
|
else
|
35
|
-
zeitwerk_original_require(path)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
35
|
+
required = zeitwerk_original_require(path)
|
36
|
+
if required
|
37
|
+
abspath = $LOADED_FEATURES.last
|
38
|
+
if loader = Zeitwerk::Registry.loader_for(abspath)
|
39
|
+
loader.on_file_autoloaded(abspath)
|
41
40
|
end
|
42
41
|
end
|
42
|
+
required
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
data/lib/zeitwerk/loader.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "set"
|
4
|
-
require "securerandom"
|
5
4
|
|
6
5
|
module Zeitwerk
|
7
6
|
class Loader
|
@@ -14,22 +13,16 @@ module Zeitwerk
|
|
14
13
|
include Helpers
|
15
14
|
include Config
|
16
15
|
|
17
|
-
#
|
18
|
-
# executed
|
16
|
+
# Maps absolute paths for which an autoload has been set ---and not
|
17
|
+
# executed--- to their corresponding parent class or module and constant
|
18
|
+
# name.
|
19
19
|
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
# and invoke user callbacks. If reloading is enabled, remember cref and
|
24
|
-
# abspath for later unloading logic.
|
25
|
-
#
|
26
|
-
# 2. When unloading, remove autoloads that have not been executed.
|
27
|
-
#
|
28
|
-
# 3. Eager load with a recursive const_get, rather than a recursive require,
|
29
|
-
# for consistency with lazy loading.
|
20
|
+
# "/Users/fxn/blog/app/models/user.rb" => [Object, :User],
|
21
|
+
# "/Users/fxn/blog/app/models/hotel/pricing.rb" => [Hotel, :Pricing]
|
22
|
+
# ...
|
30
23
|
#
|
31
24
|
# @private
|
32
|
-
# @sig
|
25
|
+
# @sig Hash[String, [Module, Symbol]]
|
33
26
|
attr_reader :autoloads
|
34
27
|
|
35
28
|
# We keep track of autoloaded directories to remove them from the registry
|
@@ -87,7 +80,7 @@ module Zeitwerk
|
|
87
80
|
def initialize
|
88
81
|
super
|
89
82
|
|
90
|
-
@autoloads =
|
83
|
+
@autoloads = {}
|
91
84
|
@autoloaded_dirs = []
|
92
85
|
@to_unload = {}
|
93
86
|
@lazy_subdirs = Hash.new { |h, cpath| h[cpath] = [] }
|
@@ -138,7 +131,7 @@ module Zeitwerk
|
|
138
131
|
# is enough.
|
139
132
|
unloaded_files = Set.new
|
140
133
|
|
141
|
-
autoloads.each do |(parent, cname)
|
134
|
+
autoloads.each do |abspath, (parent, cname)|
|
142
135
|
if parent.autoload?(cname)
|
143
136
|
unload_autoload(parent, cname)
|
144
137
|
else
|
@@ -234,7 +227,7 @@ module Zeitwerk
|
|
234
227
|
next if honour_exclusions && excluded_from_eager_load?(abspath)
|
235
228
|
|
236
229
|
if ruby?(abspath)
|
237
|
-
if cref = autoloads
|
230
|
+
if cref = autoloads[abspath]
|
238
231
|
cget(*cref)
|
239
232
|
end
|
240
233
|
elsif dir?(abspath) && !root_dirs.key?(abspath)
|
@@ -376,7 +369,7 @@ module Zeitwerk
|
|
376
369
|
|
377
370
|
# @sig (Module, Symbol, String) -> void
|
378
371
|
def autoload_subdir(parent, cname, subdir)
|
379
|
-
if autoload_path =
|
372
|
+
if autoload_path = autoload_path_set_by_me_for?(parent, cname)
|
380
373
|
cpath = cpath(parent, cname)
|
381
374
|
register_explicit_namespace(cpath) if ruby?(autoload_path)
|
382
375
|
# We do not need to issue another autoload, the existing one is enough
|
@@ -432,7 +425,7 @@ module Zeitwerk
|
|
432
425
|
|
433
426
|
# @sig (Module, Symbol, String) -> void
|
434
427
|
def set_autoload(parent, cname, abspath)
|
435
|
-
|
428
|
+
parent.autoload(cname, abspath)
|
436
429
|
|
437
430
|
if logger
|
438
431
|
if ruby?(abspath)
|
@@ -442,6 +435,7 @@ module Zeitwerk
|
|
442
435
|
end
|
443
436
|
end
|
444
437
|
|
438
|
+
autoloads[abspath] = [parent, cname]
|
445
439
|
Registry.register_autoload(self, abspath)
|
446
440
|
|
447
441
|
# See why in the documentation of Zeitwerk::Registry.inceptions.
|
@@ -450,6 +444,15 @@ module Zeitwerk
|
|
450
444
|
end
|
451
445
|
end
|
452
446
|
|
447
|
+
# @sig (Module, Symbol) -> String?
|
448
|
+
def autoload_path_set_by_me_for?(parent, cname)
|
449
|
+
if autoload_path = strict_autoload_path(parent, cname)
|
450
|
+
autoload_path if autoloads.key?(autoload_path)
|
451
|
+
else
|
452
|
+
Registry.inception?(cpath(parent, cname))
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
453
456
|
# @sig (String) -> void
|
454
457
|
def register_explicit_namespace(cpath)
|
455
458
|
ExplicitNamespace.register(cpath, self)
|
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.5.
|
4
|
+
version: 2.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Xavier Noria
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
Zeitwerk implements constant autoloading with Ruby semantics. Each gem
|
@@ -23,7 +23,6 @@ files:
|
|
23
23
|
- MIT-LICENSE
|
24
24
|
- README.md
|
25
25
|
- lib/zeitwerk.rb
|
26
|
-
- lib/zeitwerk/autoloads.rb
|
27
26
|
- lib/zeitwerk/error.rb
|
28
27
|
- lib/zeitwerk/explicit_namespace.rb
|
29
28
|
- lib/zeitwerk/gem_inflector.rb
|
@@ -55,9 +54,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
54
|
version: '2.5'
|
56
55
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
56
|
requirements:
|
58
|
-
- - "
|
57
|
+
- - ">="
|
59
58
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
59
|
+
version: '0'
|
61
60
|
requirements: []
|
62
61
|
rubygems_version: 3.2.22
|
63
62
|
signing_key:
|
data/lib/zeitwerk/autoloads.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Zeitwerk
|
4
|
-
# @private
|
5
|
-
class Autoloads
|
6
|
-
# Maps crefs for which an autoload has been defined to the corresponding
|
7
|
-
# absolute path.
|
8
|
-
#
|
9
|
-
# [Object, :User] => "/Users/fxn/blog/app/models/user.rb"
|
10
|
-
# [Object, :Hotel] => "/Users/fxn/blog/app/models/hotel"
|
11
|
-
# ...
|
12
|
-
#
|
13
|
-
# This colection is transient, callbacks delete its entries as autoloads get
|
14
|
-
# executed.
|
15
|
-
#
|
16
|
-
# @sig Hash[[Module, Symbol], String]
|
17
|
-
attr_reader :c2a
|
18
|
-
|
19
|
-
# This is the inverse of c2a, for inverse lookups.
|
20
|
-
#
|
21
|
-
# @sig Hash[String, [Module, Symbol]]
|
22
|
-
attr_reader :a2c
|
23
|
-
|
24
|
-
# @sig () -> void
|
25
|
-
def initialize
|
26
|
-
@c2a = {}
|
27
|
-
@a2c = {}
|
28
|
-
end
|
29
|
-
|
30
|
-
# @sig (Module, Symbol, String) -> void
|
31
|
-
def define(parent, cname, abspath)
|
32
|
-
parent.autoload(cname, abspath)
|
33
|
-
cref = [parent, cname]
|
34
|
-
c2a[cref] = abspath
|
35
|
-
a2c[abspath] = cref
|
36
|
-
end
|
37
|
-
|
38
|
-
# @sig () { () -> [[Module, Symbol], String] } -> void
|
39
|
-
def each(&block)
|
40
|
-
c2a.each(&block)
|
41
|
-
end
|
42
|
-
|
43
|
-
# @sig (Module, Symbol) -> String?
|
44
|
-
def abspath_for(parent, cname)
|
45
|
-
c2a[[parent, cname]]
|
46
|
-
end
|
47
|
-
|
48
|
-
# @sig (String) -> [Module, Symbol]?
|
49
|
-
def cref_for(abspath)
|
50
|
-
a2c[abspath]
|
51
|
-
end
|
52
|
-
|
53
|
-
# @sig (String) -> [Module, Symbol]?
|
54
|
-
def delete(abspath)
|
55
|
-
cref = a2c.delete(abspath)
|
56
|
-
c2a.delete(cref)
|
57
|
-
cref
|
58
|
-
end
|
59
|
-
|
60
|
-
# @sig () -> void
|
61
|
-
def clear
|
62
|
-
c2a.clear
|
63
|
-
a2c.clear
|
64
|
-
end
|
65
|
-
|
66
|
-
# @sig () -> bool
|
67
|
-
def empty?
|
68
|
-
c2a.empty? && a2c.empty?
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|