zeitwerk 2.2.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +47 -21
- data/lib/zeitwerk/loader.rb +2 -2
- data/lib/zeitwerk/loader/callbacks.rb +1 -1
- data/lib/zeitwerk/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6e1f64abc085125dd45f5c8373d793417811074dcb1d5c655c915ad393d0cf5
|
4
|
+
data.tar.gz: b4eba128f5267c2b3f40fdcd03085faae0a9063ef3a352f18b1bdbfd3031f068
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6928afbdf70077641fd07240ec8b22d4589e721fe0ab4a4008d3a880bf460b3daac3b7504151eae2320b98a55bd2e7cae3977c78d3dbfde156eca69270795362
|
7
|
+
data.tar.gz: b64df779dcb21d094d87ee739291e7798942262b05ff32ebd841dd33b237addf7551ff641fb5e4fd8d10ccdf54f25845e77860d68931e0ebf307164c5ce076fb
|
data/README.md
CHANGED
@@ -15,8 +15,9 @@
|
|
15
15
|
- [Nested root directories](#nested-root-directories)
|
16
16
|
- [Usage](#usage)
|
17
17
|
- [Setup](#setup)
|
18
|
-
- [
|
18
|
+
- [Autoloading](#autoloading)
|
19
19
|
- [Eager loading](#eager-loading)
|
20
|
+
- [Reloading](#reloading)
|
20
21
|
- [Inflection](#inflection)
|
21
22
|
- [Zeitwerk::Inflector](#zeitwerkinflector)
|
22
23
|
- [Zeitwerk::GemInflector](#zeitwerkgeminflector)
|
@@ -219,33 +220,28 @@ end
|
|
219
220
|
|
220
221
|
Zeitwerk works internally only with absolute paths to avoid costly file searches in `$LOAD_PATH`. Indeed, the root directories do not even need to belong to `$LOAD_PATH`, everything just works by design if they don't.
|
221
222
|
|
222
|
-
<a id="markdown-
|
223
|
-
###
|
223
|
+
<a id="markdown-autoloading" name="autoloading"></a>
|
224
|
+
### Autoloading
|
224
225
|
|
225
|
-
|
226
|
+
After `setup`, you are able to reference classes and modules from the project without issuing `require` calls for them. They are all available everywhere, autoloading loads them on demand. This works even if the reference to the class or module is first hit in client code, outside your project.
|
226
227
|
|
227
|
-
|
228
|
-
loader = Zeitwerk::Loader.new
|
229
|
-
loader.push_dir(...)
|
230
|
-
loader.enable_reloading # you need to opt-in before setup
|
231
|
-
loader.setup
|
232
|
-
...
|
233
|
-
loader.reload
|
234
|
-
```
|
235
|
-
|
236
|
-
There is no way to undo this, either you want to reload or you don't.
|
228
|
+
Let's revisit the example above:
|
237
229
|
|
238
|
-
|
239
|
-
|
240
|
-
Generally speaking, reloading is useful while developing running services like web applications. Gems that implement regular libraries, so to speak, or services running in testing or production environments, won't normally have a use case for reloading. If reloading is not enabled, Zeitwerk is able to use less memory.
|
230
|
+
```ruby
|
231
|
+
# lib/my_gem.rb (main file)
|
241
232
|
|
242
|
-
|
233
|
+
require "zeitwerk"
|
234
|
+
loader = Zeitwerk::Loader.for_gem
|
235
|
+
loader.setup
|
243
236
|
|
244
|
-
|
237
|
+
module MyGem
|
238
|
+
include MyLogger # (*)
|
239
|
+
end
|
240
|
+
```
|
245
241
|
|
246
|
-
|
242
|
+
That works, and there is no `require "my_gem/my_logger"`. When `(*)` is reached, Zeitwerk seamlessly autoloads `MyGem::MyLogger`.
|
247
243
|
|
248
|
-
|
244
|
+
If autoloading a file does not define the expected class or module, Zeitwerk raises `Zeitwerk::NameError`, which is a subclass of `NameError`.
|
249
245
|
|
250
246
|
<a id="markdown-eager-loading" name="eager-loading"></a>
|
251
247
|
### Eager loading
|
@@ -269,6 +265,8 @@ In gems, the method needs to be invoked after the main namespace has been define
|
|
269
265
|
|
270
266
|
Eager loading is synchronized and idempotent.
|
271
267
|
|
268
|
+
If eager loading a file does not define the expected class or module, Zeitwerk raises `Zeitwerk::NameError`, which is a subclass of `NameError`.
|
269
|
+
|
272
270
|
If you want to eager load yourself and all dependencies using Zeitwerk, you can broadcast the `eager_load` call to all instances:
|
273
271
|
|
274
272
|
```ruby
|
@@ -279,6 +277,34 @@ This may be handy in top-level services, like web applications.
|
|
279
277
|
|
280
278
|
Note that thanks to idempotence `Zeitwerk::Loader.eager_load_all` won't eager load twice if any of the instances already eager loaded.
|
281
279
|
|
280
|
+
<a id="markdown-reloading" name="reloading"></a>
|
281
|
+
### Reloading
|
282
|
+
|
283
|
+
Zeitwerk is able to reload code, but you need to enable this feature:
|
284
|
+
|
285
|
+
```ruby
|
286
|
+
loader = Zeitwerk::Loader.new
|
287
|
+
loader.push_dir(...)
|
288
|
+
loader.enable_reloading # you need to opt-in before setup
|
289
|
+
loader.setup
|
290
|
+
...
|
291
|
+
loader.reload
|
292
|
+
```
|
293
|
+
|
294
|
+
There is no way to undo this, either you want to reload or you don't.
|
295
|
+
|
296
|
+
Enabling reloading after setup raises `Zeitwerk::Error`. Attempting to reload without having it enabled raises `Zeitwerk::ReloadingDisabledError`.
|
297
|
+
|
298
|
+
Generally speaking, reloading is useful while developing running services like web applications. Gems that implement regular libraries, so to speak, or services running in testing or production environments, won't normally have a use case for reloading. If reloading is not enabled, Zeitwerk is able to use less memory.
|
299
|
+
|
300
|
+
Reloading removes the currently loaded classes and modules and resets the loader so that it will pick whatever is in the file system now.
|
301
|
+
|
302
|
+
It is important to highlight that this is an instance method. Don't worry about project dependencies managed by Zeitwerk, their loaders are independent.
|
303
|
+
|
304
|
+
In order for reloading to be thread-safe, you need to implement some coordination. For example, a web framework that serves each request with its own thread may have a globally accessible RW lock. When a request comes in, the framework acquires the lock for reading at the beginning, and the code in the framework that calls `loader.reload` needs to acquire the lock for writing.
|
305
|
+
|
306
|
+
On reloading, client code has to update anything that would otherwise be storing a stale object. For example, if the routing layer of a web framework stores controller class objects or instances in internal structures, on reload it has to refresh them somehow, possibly reevaluating routes.
|
307
|
+
|
282
308
|
<a id="markdown-inflection" name="inflection"></a>
|
283
309
|
### Inflection
|
284
310
|
|
data/lib/zeitwerk/loader.rb
CHANGED
@@ -494,7 +494,7 @@ module Zeitwerk
|
|
494
494
|
rescue ::NameError => error
|
495
495
|
path_type = ruby?(abspath) ? "file" : "directory"
|
496
496
|
|
497
|
-
raise NameError,
|
497
|
+
raise NameError.new(<<~MESSAGE, error.name)
|
498
498
|
#{error.message} inferred by #{inflector.class} from #{path_type}
|
499
499
|
|
500
500
|
#{abspath}
|
@@ -558,7 +558,7 @@ module Zeitwerk
|
|
558
558
|
end
|
559
559
|
|
560
560
|
# @param dir [String] directory that would have autovivified a module
|
561
|
-
# @param file [String] the file where the namespace is
|
561
|
+
# @param file [String] the file where the namespace is explicitly defined
|
562
562
|
# @param parent [Module]
|
563
563
|
# @param cname [Symbol]
|
564
564
|
# @return [void]
|
@@ -14,7 +14,7 @@ module Zeitwerk::Loader::Callbacks
|
|
14
14
|
if logger && cdef?(*cref)
|
15
15
|
log("constant #{cpath(*cref)} loaded from file #{file}")
|
16
16
|
elsif !cdef?(*cref)
|
17
|
-
raise Zeitwerk::NameError
|
17
|
+
raise Zeitwerk::NameError.new("expected file #{file} to define constant #{cpath(*cref)}, but didn't", cref.last)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
data/lib/zeitwerk/version.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.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Xavier Noria
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
Zeitwerk implements constant autoloading with Ruby semantics. Each gem
|