zeitwerk 2.4.0 → 2.4.1

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: 682fa352a9d6d4bf68d07cf2cbfbb539de3cfec4e8af2f930894ab27c707ca93
4
- data.tar.gz: 1e7ce6157e6046cdb60f0f1b531f1f39fb97cad3537392114be5cf84dae672c9
3
+ metadata.gz: b0c408b8f6001e150b16b1e06b1b05d31bcbf4f0144535c995093c822065be3d
4
+ data.tar.gz: af26de0ecd68b8ebc1836ea431d59c6d7e10d79937c402e3529fc4275631c950
5
5
  SHA512:
6
- metadata.gz: e308baba1a8fbe4d7c64d7195c753d795a53caefa7264d2404117cb620f2081f6b0fc05c056dafb035b44430102e4472b7eb9fb3a4fd9d70aa124b7f9a3a8313
7
- data.tar.gz: 5139d5abaeed86e256493b592460b13b19fd7602f7c099f7017b55af9f16a91429e84074a4e31fe79bf28235e02cbba3055cc4bda579bbc7de2a391c5997a393
6
+ metadata.gz: 012c9a70cd31973a7251f46f62c102bf11155a6ea90dcdfa62bb2cd1859fca07cfed268dd130528fc55eab4ea0d440347e7ed0cb78f54dca861f96f56014541d
7
+ data.tar.gz: 7243c0f9b6c39dd389f0570fe03f11a8cadb01b74ae5d5efaa9b895ecf3b2717b5eb71e027c555f1cfeb95457dd5f5d8ace4516eb3a77500b05b1c8f973c1a94
data/README.md CHANGED
@@ -151,7 +151,7 @@ require "active_job/queue_adapters"
151
151
  loader.push_dir("#{__dir__}/adapters", namespace: ActiveJob::QueueAdapters)
152
152
  ```
153
153
 
154
- your adapter can be stored directly in that directory instead of the canonical `lib/active_job/queue_adapters`.
154
+ your adapter can be stored directly in that directory instead of the canonical `#{__dir__}/active_job/queue_adapters`.
155
155
 
156
156
  Please, note that the given namespace must be non-reloadable, though autoloaded constants in that namespace can be. That is, if you associate `app/api` with an existing `Api` module, that module should not be reloadable. However, if the project defines and autoloads the class `Api::V2::Deliveries`, that one can be reloaded.
157
157
 
@@ -202,7 +202,7 @@ booking/actions/create.rb -> Booking::Create
202
202
  To make it work that way, configure Zeitwerk to collapse said directory:
203
203
 
204
204
  ```ruby
205
- loader.collapse("booking/actions")
205
+ loader.collapse("#{__dir__}/booking/actions")
206
206
  ```
207
207
 
208
208
  This method accepts an arbitrary number of strings or `Pathname` objects, and also an array of them.
@@ -212,7 +212,7 @@ You can pass directories and glob patterns. Glob patterns are expanded when they
212
212
  To illustrate usage of glob patterns, if `actions` in the example above is part of a standardized structure, you could use a wildcard:
213
213
 
214
214
  ```ruby
215
- loader.collapse("*/actions")
215
+ loader.collapse("#{__dir__}/*/actions")
216
216
  ```
217
217
 
218
218
  <a id="markdown-nested-root-directories" name="nested-root-directories"></a>
@@ -14,24 +14,22 @@ module Zeitwerk
14
14
  # the file system, to the loader responsible for them.
15
15
  #
16
16
  # @private
17
- # @return [{String => Zeitwerk::Loader}]
17
+ # @sig Hash[String, Zeitwerk::Loader]
18
18
  attr_reader :cpaths
19
19
 
20
20
  # @private
21
- # @return [Mutex]
21
+ # @sig Mutex
22
22
  attr_reader :mutex
23
23
 
24
24
  # @private
25
- # @return [TracePoint]
25
+ # @sig TracePoint
26
26
  attr_reader :tracer
27
27
 
28
28
  # Asserts `cpath` corresponds to an explicit namespace for which `loader`
29
29
  # is responsible.
30
30
  #
31
31
  # @private
32
- # @param cpath [String]
33
- # @param loader [Zeitwerk::Loader]
34
- # @return [void]
32
+ # @sig (String, Zeitwerk::Loader) -> void
35
33
  def register(cpath, loader)
36
34
  mutex.synchronize do
37
35
  cpaths[cpath] = loader
@@ -42,19 +40,22 @@ module Zeitwerk
42
40
  end
43
41
 
44
42
  # @private
45
- # @param loader [Zeitwerk::Loader]
46
- # @return [void]
43
+ # @sig (Zeitwerk::Loader) -> void
47
44
  def unregister(loader)
48
45
  cpaths.delete_if { |_cpath, l| l == loader }
49
46
  disable_tracer_if_unneeded
50
47
  end
51
48
 
49
+ private
50
+
51
+ # @sig () -> void
52
52
  def disable_tracer_if_unneeded
53
53
  mutex.synchronize do
54
54
  tracer.disable if cpaths.empty?
55
55
  end
56
56
  end
57
57
 
58
+ # @sig (TracePoint) -> void
58
59
  def tracepoint_class_callback(event)
59
60
  # If the class is a singleton class, we won't do anything with it so we
60
61
  # can bail out immediately. This is several orders of magnitude faster
@@ -2,16 +2,14 @@
2
2
 
3
3
  module Zeitwerk
4
4
  class GemInflector < Inflector
5
- # @param root_file [String]
5
+ # @sig (String) -> void
6
6
  def initialize(root_file)
7
7
  namespace = File.basename(root_file, ".rb")
8
8
  lib_dir = File.dirname(root_file)
9
9
  @version_file = File.join(lib_dir, namespace, "version.rb")
10
10
  end
11
11
 
12
- # @param basename [String]
13
- # @param abspath [String]
14
- # @return [String]
12
+ # @sig (String, String) -> String
15
13
  def camelize(basename, abspath)
16
14
  abspath == @version_file ? "VERSION" : super
17
15
  end
@@ -11,9 +11,7 @@ module Zeitwerk
11
11
  #
12
12
  # Takes into account hard-coded mappings configured with `inflect`.
13
13
  #
14
- # @param basename [String]
15
- # @param _abspath [String]
16
- # @return [String]
14
+ # @sig (String, String) -> String
17
15
  def camelize(basename, _abspath)
18
16
  overrides[basename] || basename.split('_').each(&:capitalize!).join
19
17
  end
@@ -30,8 +28,7 @@ module Zeitwerk
30
28
  # inflector.camelize("mysql_adapter", abspath) # => "MySQLAdapter"
31
29
  # inflector.camelize("users_controller", abspath) # => "UsersController"
32
30
  #
33
- # @param inflections [{String => String}]
34
- # @return [void]
31
+ # @sig (Hash[String, String]) -> void
35
32
  def inflect(inflections)
36
33
  overrides.merge!(inflections)
37
34
  end
@@ -41,7 +38,7 @@ module Zeitwerk
41
38
  # Hard-coded basename to constant name user maps that override the default
42
39
  # inflection logic.
43
40
  #
44
- # @return [{String => String}]
41
+ # @sig () -> Hash[String, String]
45
42
  def overrides
46
43
  @overrides ||= {}
47
44
  end
@@ -19,8 +19,7 @@ module Kernel
19
19
  # already existing ancestor chains.
20
20
  alias_method :zeitwerk_original_require, :require
21
21
 
22
- # @param path [String]
23
- # @return [Boolean]
22
+ # @sig (String) -> true | false
24
23
  def require(path)
25
24
  if loader = Zeitwerk::Registry.loader_for(path)
26
25
  if path.end_with?(".rb")
@@ -9,13 +9,13 @@ module Zeitwerk
9
9
  include Callbacks
10
10
  include RealModName
11
11
 
12
- # @return [String]
12
+ # @sig String
13
13
  attr_reader :tag
14
14
 
15
- # @return [#camelize]
15
+ # @sig #camelize
16
16
  attr_accessor :inflector
17
17
 
18
- # @return [#call, #debug, nil]
18
+ # @sig #call | #debug | nil
19
19
  attr_accessor :logger
20
20
 
21
21
  # Absolute paths of the root directories. Stored in a hash to preserve
@@ -30,20 +30,20 @@ module Zeitwerk
30
30
  # interface for it is `push_dir` and `dirs`.
31
31
  #
32
32
  # @private
33
- # @return [{String => true}]
33
+ # @sig Hash[String, true]
34
34
  attr_reader :root_dirs
35
35
 
36
36
  # Absolute paths of files or directories that have to be preloaded.
37
37
  #
38
38
  # @private
39
- # @return [<String>]
39
+ # @sig Array[String]
40
40
  attr_reader :preloads
41
41
 
42
42
  # Absolute paths of files, directories, or glob patterns to be totally
43
43
  # ignored.
44
44
  #
45
45
  # @private
46
- # @return [Set<String>]
46
+ # @sig Set[String]
47
47
  attr_reader :ignored_glob_patterns
48
48
 
49
49
  # The actual collection of absolute file and directory names at the time the
@@ -51,20 +51,20 @@ module Zeitwerk
51
51
  # reload.
52
52
  #
53
53
  # @private
54
- # @return [Set<String>]
54
+ # @sig Set[String]
55
55
  attr_reader :ignored_paths
56
56
 
57
57
  # Absolute paths of directories or glob patterns to be collapsed.
58
58
  #
59
59
  # @private
60
- # @return [Set<String>]
60
+ # @sig Set[String]
61
61
  attr_reader :collapse_glob_patterns
62
62
 
63
63
  # The actual collection of absolute directory names at the time the collapse
64
64
  # glob patterns were expanded. Computed on setup, and recomputed on reload.
65
65
  #
66
66
  # @private
67
- # @return [Set<String>]
67
+ # @sig Set[String]
68
68
  attr_reader :collapse_dirs
69
69
 
70
70
  # Maps real absolute paths for which an autoload has been set ---and not
@@ -76,7 +76,7 @@ module Zeitwerk
76
76
  # ...
77
77
  #
78
78
  # @private
79
- # @return [{String => (Module, Symbol)}]
79
+ # @sig Hash[String, [Module, Symbol]]
80
80
  attr_reader :autoloads
81
81
 
82
82
  # We keep track of autoloaded directories to remove them from the registry
@@ -86,7 +86,7 @@ module Zeitwerk
86
86
  # to concurrency (see why in Zeitwerk::Loader::Callbacks#on_dir_autoloaded).
87
87
  #
88
88
  # @private
89
- # @return [<String>]
89
+ # @sig Array[String]
90
90
  attr_reader :autoloaded_dirs
91
91
 
92
92
  # Stores metadata needed for unloading. Its entries look like this:
@@ -102,7 +102,7 @@ module Zeitwerk
102
102
  # or eager loaded. Otherwise, the collection remains empty.
103
103
  #
104
104
  # @private
105
- # @return [{String => (String, (Module, Symbol))}]
105
+ # @sig Hash[String, [String, [Module, Symbol]]]
106
106
  attr_reader :to_unload
107
107
 
108
108
  # Maps constant paths of namespaces to arrays of corresponding directories.
@@ -120,21 +120,21 @@ module Zeitwerk
120
120
  # up the corresponding autoloads.
121
121
  #
122
122
  # @private
123
- # @return [{String => <String>}]
123
+ # @sig Hash[String, Array[String]]
124
124
  attr_reader :lazy_subdirs
125
125
 
126
126
  # Absolute paths of files or directories not to be eager loaded.
127
127
  #
128
128
  # @private
129
- # @return [Set<String>]
129
+ # @sig Set[String]
130
130
  attr_reader :eager_load_exclusions
131
131
 
132
132
  # @private
133
- # @return [Mutex]
133
+ # @sig Mutex
134
134
  attr_reader :mutex
135
135
 
136
136
  # @private
137
- # @return [Mutex]
137
+ # @sig Mutex
138
138
  attr_reader :mutex2
139
139
 
140
140
  def initialize
@@ -170,7 +170,7 @@ module Zeitwerk
170
170
  # Sets a tag for the loader, useful for logging.
171
171
  #
172
172
  # @param tag [#to_s]
173
- # @return [void]
173
+ # @sig (#to_s) -> void
174
174
  def tag=(tag)
175
175
  @tag = tag.to_s
176
176
  end
@@ -178,7 +178,7 @@ module Zeitwerk
178
178
  # Absolute paths of the root directories. This is a read-only collection,
179
179
  # please push here via `push_dir`.
180
180
  #
181
- # @return [<String>]
181
+ # @sig () -> Array[String]
182
182
  def dirs
183
183
  root_dirs.keys.freeze
184
184
  end
@@ -189,10 +189,8 @@ module Zeitwerk
189
189
  # the same process already manages that directory or one of its ascendants
190
190
  # or descendants.
191
191
  #
192
- # @param path [<String, Pathname>]
193
- # @param namespace [Class, Module]
194
192
  # @raise [Zeitwerk::Error]
195
- # @return [void]
193
+ # @sig (String | Pathname, Module) -> void
196
194
  def push_dir(path, namespace: Object)
197
195
  # Note that Class < Module.
198
196
  unless namespace.is_a?(Module)
@@ -212,7 +210,7 @@ module Zeitwerk
212
210
  # There is no way to undo this, either you want to reload or you don't.
213
211
  #
214
212
  # @raise [Zeitwerk::Error]
215
- # @return [void]
213
+ # @sig () -> void
216
214
  def enable_reloading
217
215
  mutex.synchronize do
218
216
  break if @reloading_enabled
@@ -225,15 +223,14 @@ module Zeitwerk
225
223
  end
226
224
  end
227
225
 
228
- # @return [Boolean]
226
+ # @sig () -> bool
229
227
  def reloading_enabled?
230
228
  @reloading_enabled
231
229
  end
232
230
 
233
231
  # Files or directories to be preloaded instead of lazy loaded.
234
232
  #
235
- # @param paths [<String, Pathname, <String, Pathname>>]
236
- # @return [void]
233
+ # @sig (*(String | Pathname | Array[String | Pathname])) -> void
237
234
  def preload(*paths)
238
235
  mutex.synchronize do
239
236
  expand_paths(paths).each do |abspath|
@@ -245,8 +242,7 @@ module Zeitwerk
245
242
 
246
243
  # Configure files, directories, or glob patterns to be totally ignored.
247
244
  #
248
- # @param paths [<String, Pathname, <String, Pathname>>]
249
- # @return [void]
245
+ # @sig (*(String | Pathname | Array[String | Pathname])) -> void
250
246
  def ignore(*glob_patterns)
251
247
  glob_patterns = expand_paths(glob_patterns)
252
248
  mutex.synchronize do
@@ -257,8 +253,7 @@ module Zeitwerk
257
253
 
258
254
  # Configure directories or glob patterns to be collapsed.
259
255
  #
260
- # @param paths [<String, Pathname, <String, Pathname>>]
261
- # @return [void]
256
+ # @sig (*(String | Pathname | Array[String | Pathname])) -> void
262
257
  def collapse(*glob_patterns)
263
258
  glob_patterns = expand_paths(glob_patterns)
264
259
  mutex.synchronize do
@@ -269,7 +264,7 @@ module Zeitwerk
269
264
 
270
265
  # Sets autoloads in the root namespace and preloads files, if any.
271
266
  #
272
- # @return [void]
267
+ # @sig () -> void
273
268
  def setup
274
269
  mutex.synchronize do
275
270
  break if @setup
@@ -291,7 +286,7 @@ module Zeitwerk
291
286
  # unload them.
292
287
  #
293
288
  # @private
294
- # @return [void]
289
+ # @sig () -> void
295
290
  def unload
296
291
  mutex.synchronize do
297
292
  # We are going to keep track of the files that were required by our
@@ -354,7 +349,7 @@ module Zeitwerk
354
349
  # client code in the README of the project.
355
350
  #
356
351
  # @raise [Zeitwerk::Error]
357
- # @return [void]
352
+ # @sig () -> void
358
353
  def reload
359
354
  if reloading_enabled?
360
355
  unload
@@ -371,7 +366,7 @@ module Zeitwerk
371
366
  # are not eager loaded. You can opt-out specifically in specific files and
372
367
  # directories with `do_not_eager_load`.
373
368
  #
374
- # @return [void]
369
+ # @sig () -> void
375
370
  def eager_load
376
371
  mutex.synchronize do
377
372
  break if @eager_loaded
@@ -414,8 +409,7 @@ module Zeitwerk
414
409
  # Let eager load ignore the given files or directories. The constants
415
410
  # defined in those files are still autoloadable.
416
411
  #
417
- # @param paths [<String, Pathname, <String, Pathname>>]
418
- # @return [void]
412
+ # @sig (*(String | Pathname | Array[String | Pathname])) -> void
419
413
  def do_not_eager_load(*paths)
420
414
  mutex.synchronize { eager_load_exclusions.merge(expand_paths(paths)) }
421
415
  end
@@ -423,8 +417,7 @@ module Zeitwerk
423
417
  # Says if the given constant path would be unloaded on reload. This
424
418
  # predicate returns `false` if reloading is disabled.
425
419
  #
426
- # @param cpath [String]
427
- # @return [Boolean]
420
+ # @sig (String) -> bool
428
421
  def unloadable_cpath?(cpath)
429
422
  to_unload.key?(cpath)
430
423
  end
@@ -432,21 +425,20 @@ module Zeitwerk
432
425
  # Returns an array with the constant paths that would be unloaded on reload.
433
426
  # This predicate returns an empty array if reloading is disabled.
434
427
  #
435
- # @return [<String>]
428
+ # @sig () -> Array[String]
436
429
  def unloadable_cpaths
437
430
  to_unload.keys.freeze
438
431
  end
439
432
 
440
433
  # Logs to `$stdout`, handy shortcut for debugging.
441
434
  #
442
- # @return [void]
435
+ # @sig () -> void
443
436
  def log!
444
437
  @logger = ->(msg) { puts msg }
445
438
  end
446
439
 
447
440
  # @private
448
- # @param dir [String]
449
- # @return [Boolean]
441
+ # @sig (String) -> bool
450
442
  def manages?(dir)
451
443
  dir = dir + "/"
452
444
  ignored_paths.each do |ignored_path|
@@ -463,11 +455,11 @@ module Zeitwerk
463
455
  # --- Class methods ---------------------------------------------------------------------------
464
456
 
465
457
  class << self
466
- # @return [#call, #debug, nil]
458
+ # @sig #call | #debug | nil
467
459
  attr_accessor :default_logger
468
460
 
469
461
  # @private
470
- # @return [Mutex]
462
+ # @sig Mutex
471
463
  attr_accessor :mutex
472
464
 
473
465
  # This is a shortcut for
@@ -481,7 +473,7 @@ module Zeitwerk
481
473
  # except that this method returns the same object in subsequent calls from
482
474
  # the same file, in the unlikely case the gem wants to be able to reload.
483
475
  #
484
- # @return [Zeitwerk::Loader]
476
+ # @sig () -> Zeitwerk::Loader
485
477
  def for_gem
486
478
  called_from = caller_locations(1, 1).first.path
487
479
  Registry.loader_for_gem(called_from)
@@ -489,7 +481,7 @@ module Zeitwerk
489
481
 
490
482
  # Broadcasts `eager_load` to all loaders.
491
483
  #
492
- # @return [void]
484
+ # @sig () -> void
493
485
  def eager_load_all
494
486
  Registry.loaders.each(&:eager_load)
495
487
  end
@@ -497,7 +489,7 @@ module Zeitwerk
497
489
  # Returns an array with the absolute paths of the root directories of all
498
490
  # registered loaders. This is a read-only collection.
499
491
  #
500
- # @return [<String>]
492
+ # @sig () -> Array[String]
501
493
  def all_dirs
502
494
  Registry.loaders.flat_map(&:dirs).freeze
503
495
  end
@@ -507,16 +499,14 @@ module Zeitwerk
507
499
 
508
500
  private # -------------------------------------------------------------------------------------
509
501
 
510
- # @return [<String>]
502
+ # @sig () -> Array[String]
511
503
  def actual_root_dirs
512
504
  root_dirs.reject do |root_dir, _namespace|
513
505
  !dir?(root_dir) || ignored_paths.member?(root_dir)
514
506
  end
515
507
  end
516
508
 
517
- # @param dir [String]
518
- # @param parent [Module]
519
- # @return [void]
509
+ # @sig (String, Module) -> void
520
510
  def set_autoloads_in_dir(dir, parent)
521
511
  ls(dir) do |basename, abspath|
522
512
  begin
@@ -559,10 +549,7 @@ module Zeitwerk
559
549
  end
560
550
  end
561
551
 
562
- # @param parent [Module]
563
- # @param cname [Symbol]
564
- # @param subdir [String]
565
- # @return [void]
552
+ # @sig (Module, Symbol, String) -> void
566
553
  def autoload_subdir(parent, cname, subdir)
567
554
  if autoload_path = autoload_for?(parent, cname)
568
555
  cpath = cpath(parent, cname)
@@ -582,10 +569,7 @@ module Zeitwerk
582
569
  end
583
570
  end
584
571
 
585
- # @param parent [Module]
586
- # @param cname [Symbol]
587
- # @param file [String]
588
- # @return [void]
572
+ # @sig (Module, Symbol, String) -> void
589
573
  def autoload_file(parent, cname, file)
590
574
  if autoload_path = autoload_for?(parent, cname)
591
575
  # First autoload for a Ruby file wins, just ignore subsequent ones.
@@ -606,11 +590,10 @@ module Zeitwerk
606
590
  end
607
591
  end
608
592
 
609
- # @param dir [String] directory that would have autovivified a module
610
- # @param file [String] the file where the namespace is explicitly defined
611
- # @param parent [Module]
612
- # @param cname [Symbol]
613
- # @return [void]
593
+ # `dir` is the directory that would have autovivified a namespace. `file` is
594
+ # the file where we've found the namespace is explicitly defined.
595
+ #
596
+ # @sig (dir: String, file: String, parent: Module, cname: Symbol) -> void
614
597
  def promote_namespace_from_implicit_to_explicit(dir:, file:, parent:, cname:)
615
598
  autoloads.delete(dir)
616
599
  Registry.unregister_autoload(dir)
@@ -619,10 +602,7 @@ module Zeitwerk
619
602
  register_explicit_namespace(cpath(parent, cname))
620
603
  end
621
604
 
622
- # @param parent [Module]
623
- # @param cname [Symbol]
624
- # @param abspath [String]
625
- # @return [void]
605
+ # @sig (Module, Symbol, String) -> void
626
606
  def set_autoload(parent, cname, abspath)
627
607
  # $LOADED_FEATURES stores real paths since Ruby 2.4.4. We set and save the
628
608
  # real path to be able to delete it from $LOADED_FEATURES on unload, and to
@@ -649,9 +629,7 @@ module Zeitwerk
649
629
  end
650
630
  end
651
631
 
652
- # @param parent [Module]
653
- # @param cname [Symbol]
654
- # @return [String, nil]
632
+ # @sig (Module, Symbol) -> String?
655
633
  def autoload_for?(parent, cname)
656
634
  strict_autoload_path(parent, cname) || Registry.inception?(cpath(parent, cname))
657
635
  end
@@ -672,9 +650,7 @@ module Zeitwerk
672
650
  #
673
651
  # We need a way to strictly check in parent ignoring ancestors.
674
652
  #
675
- # @param parent [Module]
676
- # @param cname [Symbol]
677
- # @return [String, nil]
653
+ # @sig (Module, Symbol) -> String?
678
654
  if method(:autoload?).arity == 1
679
655
  def strict_autoload_path(parent, cname)
680
656
  parent.autoload?(cname) if cdef?(parent, cname)
@@ -688,15 +664,14 @@ module Zeitwerk
688
664
  # This method is called this way because I prefer `preload` to be the method
689
665
  # name to configure preloads in the public interface.
690
666
  #
691
- # @return [void]
667
+ # @sig () -> void
692
668
  def do_preload
693
669
  preloads.each do |abspath|
694
670
  do_preload_abspath(abspath)
695
671
  end
696
672
  end
697
673
 
698
- # @param abspath [String]
699
- # @return [void]
674
+ # @sig (String) -> void
700
675
  def do_preload_abspath(abspath)
701
676
  if ruby?(abspath)
702
677
  do_preload_file(abspath)
@@ -705,31 +680,25 @@ module Zeitwerk
705
680
  end
706
681
  end
707
682
 
708
- # @param dir [String]
709
- # @return [void]
683
+ # @sig (String) -> void
710
684
  def do_preload_dir(dir)
711
685
  ls(dir) do |_basename, abspath|
712
686
  do_preload_abspath(abspath)
713
687
  end
714
688
  end
715
689
 
716
- # @param file [String]
717
- # @return [Boolean]
690
+ # @sig (String) -> bool
718
691
  def do_preload_file(file)
719
692
  log("preloading #{file}") if logger
720
693
  require file
721
694
  end
722
695
 
723
- # @param parent [Module]
724
- # @param cname [Symbol]
725
- # @return [String]
696
+ # @sig (Module, Symbol) -> String
726
697
  def cpath(parent, cname)
727
698
  parent.equal?(Object) ? cname.to_s : "#{real_mod_name(parent)}::#{cname}"
728
699
  end
729
700
 
730
- # @param dir [String]
731
- # @yieldparam path [String, String]
732
- # @return [void]
701
+ # @sig (String) { (String, String) -> void } -> void
733
702
  def ls(dir)
734
703
  Dir.foreach(dir) do |basename|
735
704
  next if basename.start_with?(".")
@@ -743,57 +712,55 @@ module Zeitwerk
743
712
  end
744
713
  end
745
714
 
746
- # @param path [String]
747
- # @return [Boolean]
715
+ # @sig (String) -> bool
748
716
  def ruby?(path)
749
717
  path.end_with?(".rb")
750
718
  end
751
719
 
752
- # @param path [String]
753
- # @return [Boolean]
720
+ # @sig (String) -> bool
754
721
  def dir?(path)
755
722
  File.directory?(path)
756
723
  end
757
724
 
758
- # @param paths [<String, Pathname, <String, Pathname>>]
759
- # @return [<String>]
725
+ # @sig (String | Pathname | Array[String | Pathname]) -> Array[String]
760
726
  def expand_paths(paths)
761
727
  paths.flatten.map! { |path| File.expand_path(path) }
762
728
  end
763
729
 
764
- # @param glob_patterns [<String>]
765
- # @return [<String>]
730
+ # @sig (Array[String]) -> Array[String]
766
731
  def expand_glob_patterns(glob_patterns)
767
732
  # Note that Dir.glob works with regular file names just fine. That is,
768
733
  # glob patterns technically need no wildcards.
769
734
  glob_patterns.flat_map { |glob_pattern| Dir.glob(glob_pattern) }
770
735
  end
771
736
 
772
- # @return [void]
737
+ # @sig () -> void
773
738
  def recompute_ignored_paths
774
739
  ignored_paths.replace(expand_glob_patterns(ignored_glob_patterns))
775
740
  end
776
741
 
777
- # @return [void]
742
+ # @sig () -> void
778
743
  def recompute_collapse_dirs
779
744
  collapse_dirs.replace(expand_glob_patterns(collapse_glob_patterns))
780
745
  end
781
746
 
782
- # @param message [String]
783
- # @return [void]
747
+ # @sig (String) -> void
784
748
  def log(message)
785
749
  method_name = logger.respond_to?(:debug) ? :debug : :call
786
750
  logger.send(method_name, "Zeitwerk@#{tag}: #{message}")
787
751
  end
788
752
 
753
+ # @sig (Module, Symbol) -> bool
789
754
  def cdef?(parent, cname)
790
755
  parent.const_defined?(cname, false)
791
756
  end
792
757
 
758
+ # @sig (String) -> void
793
759
  def register_explicit_namespace(cpath)
794
760
  ExplicitNamespace.register(cpath, self)
795
761
  end
796
762
 
763
+ # @sig (String) -> void
797
764
  def raise_if_conflicting_directory(dir)
798
765
  self.class.mutex.synchronize do
799
766
  Registry.loaders.each do |loader|
@@ -808,19 +775,15 @@ module Zeitwerk
808
775
  end
809
776
  end
810
777
 
811
- # @param parent [Module]
812
- # @param cname [Symbol]
813
- # @return [void]
778
+ # @sig (Module, Symbol) -> void
814
779
  def unload_autoload(parent, cname)
815
- parent.send(:remove_const, cname)
780
+ parent.__send__(:remove_const, cname)
816
781
  log("autoload for #{cpath(parent, cname)} removed") if logger
817
782
  end
818
783
 
819
- # @param parent [Module]
820
- # @param cname [Symbol]
821
- # @return [void]
784
+ # @sig (Module, Symbol) -> void
822
785
  def unload_cref(parent, cname)
823
- parent.send(:remove_const, cname)
786
+ parent.__send__(:remove_const, cname)
824
787
  log("#{cpath(parent, cname)} unloaded") if logger
825
788
  end
826
789
  end
@@ -4,8 +4,7 @@ module Zeitwerk::Loader::Callbacks
4
4
  # Invoked from our decorated Kernel#require when a managed file is autoloaded.
5
5
  #
6
6
  # @private
7
- # @param file [String]
8
- # @return [void]
7
+ # @sig (String) -> void
9
8
  def on_file_autoloaded(file)
10
9
  cref = autoloads.delete(file)
11
10
  to_unload[cpath(*cref)] = [file, cref] if reloading_enabled?
@@ -22,8 +21,7 @@ module Zeitwerk::Loader::Callbacks
22
21
  # autoloaded.
23
22
  #
24
23
  # @private
25
- # @param dir [String]
26
- # @return [void]
24
+ # @sig (String) -> void
27
25
  def on_dir_autoloaded(dir)
28
26
  # Module#autoload does not serialize concurrent requires, and we handle
29
27
  # directories ourselves, so the callback needs to account for concurrency.
@@ -59,8 +57,7 @@ module Zeitwerk::Loader::Callbacks
59
57
  # subdirectories, we descend into them now.
60
58
  #
61
59
  # @private
62
- # @param namespace [Module]
63
- # @return [void]
60
+ # @sig (Module) -> void
64
61
  def on_namespace_loaded(namespace)
65
62
  if subdirs = lazy_subdirs.delete(real_mod_name(namespace))
66
63
  subdirs.each do |subdir|
@@ -7,8 +7,7 @@ module Zeitwerk::RealModName
7
7
  #
8
8
  # The name method can be overridden, hence the indirection in this method.
9
9
  #
10
- # @param mod [Class, Module]
11
- # @return [String, nil]
10
+ # @sig (Module) -> String?
12
11
  if UnboundMethod.method_defined?(:bind_call)
13
12
  def real_mod_name(mod)
14
13
  UNBOUND_METHOD_MODULE_NAME.bind_call(mod)
@@ -7,14 +7,14 @@ module Zeitwerk
7
7
  # them from being garbage collected.
8
8
  #
9
9
  # @private
10
- # @return [<Zeitwerk::Loader>]
10
+ # @sig Array[Zeitwerk::Loader]
11
11
  attr_reader :loaders
12
12
 
13
13
  # Registers loaders created with `for_gem` to make the method idempotent
14
14
  # in case of reload.
15
15
  #
16
16
  # @private
17
- # @return [{String => Zeitwerk::Loader}]
17
+ # @sig Hash[String, Zeitwerk::Loader]
18
18
  attr_reader :loaders_managing_gems
19
19
 
20
20
  # Maps real paths to the loaders responsible for them.
@@ -23,7 +23,7 @@ module Zeitwerk
23
23
  # invoke callbacks and autovivify modules.
24
24
  #
25
25
  # @private
26
- # @return [{String => Zeitwerk::Loader}]
26
+ # @sig Hash[String, Zeitwerk::Loader]
27
27
  attr_reader :autoloads
28
28
 
29
29
  # This hash table addresses an edge case in which an autoload is ignored.
@@ -62,14 +62,13 @@ module Zeitwerk
62
62
  # end
63
63
  #
64
64
  # @private
65
- # @return [{String => (String, Zeitwerk::Loader)}]
65
+ # @sig Hash[String, [String, Zeitwerk::Loader]]
66
66
  attr_reader :inceptions
67
67
 
68
68
  # Registers a loader.
69
69
  #
70
70
  # @private
71
- # @param loader [Zeitwerk::Loader]
72
- # @return [void]
71
+ # @sig (Zeitwerk::Loader) -> void
73
72
  def register_loader(loader)
74
73
  loaders << loader
75
74
  end
@@ -78,8 +77,7 @@ module Zeitwerk
78
77
  # file. That is how Zeitwerk::Loader.for_gem is idempotent.
79
78
  #
80
79
  # @private
81
- # @param root_file [String]
82
- # @return [Zeitwerk::Loader]
80
+ # @sig (String) -> Zeitwerk::Loader
83
81
  def loader_for_gem(root_file)
84
82
  loaders_managing_gems[root_file] ||= begin
85
83
  Loader.new.tap do |loader|
@@ -91,32 +89,25 @@ module Zeitwerk
91
89
  end
92
90
 
93
91
  # @private
94
- # @param loader [Zeitwerk::Loader]
95
- # @param realpath [String]
96
- # @return [void]
92
+ # @sig (Zeitwerk::Loader, String) -> String
97
93
  def register_autoload(loader, realpath)
98
94
  autoloads[realpath] = loader
99
95
  end
100
96
 
101
97
  # @private
102
- # @param realpath [String]
103
- # @return [void]
98
+ # @sig (String) -> void
104
99
  def unregister_autoload(realpath)
105
100
  autoloads.delete(realpath)
106
101
  end
107
102
 
108
103
  # @private
109
- # @param cpath [String]
110
- # @param realpath [String]
111
- # @param loader [Zeitwerk::Loader]
112
- # @return [void]
104
+ # @sig (String, String, Zeitwerk::Loader) -> void
113
105
  def register_inception(cpath, realpath, loader)
114
106
  inceptions[cpath] = [realpath, loader]
115
107
  end
116
108
 
117
109
  # @private
118
- # @param cpath [String]
119
- # @return [String, nil]
110
+ # @sig (String) -> String?
120
111
  def inception?(cpath)
121
112
  if pair = inceptions[cpath]
122
113
  pair.first
@@ -124,15 +115,13 @@ module Zeitwerk
124
115
  end
125
116
 
126
117
  # @private
127
- # @param path [String]
128
- # @return [Zeitwerk::Loader, nil]
118
+ # @sig (String) -> Zeitwerk::Loader?
129
119
  def loader_for(path)
130
120
  autoloads[path]
131
121
  end
132
122
 
133
123
  # @private
134
- # @param loader [Zeitwerk::Loader]
135
- # @return [void]
124
+ # @sig (Zeitwerk::Loader) -> void
136
125
  def on_unload(loader)
137
126
  autoloads.delete_if { |_path, object| object == loader }
138
127
  inceptions.delete_if { |_cpath, (_path, object)| object == loader }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zeitwerk
4
- VERSION = "2.4.0"
4
+ VERSION = "2.4.1"
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.4.0
4
+ version: 2.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xavier Noria
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-14 00:00:00.000000000 Z
11
+ date: 2020-10-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  Zeitwerk implements constant autoloading with Ruby semantics. Each gem
@@ -41,7 +41,7 @@ metadata:
41
41
  changelog_uri: https://github.com/fxn/zeitwerk/blob/master/CHANGELOG.md
42
42
  source_code_uri: https://github.com/fxn/zeitwerk
43
43
  bug_tracker_uri: https://github.com/fxn/zeitwerk/issues
44
- post_install_message:
44
+ post_install_message:
45
45
  rdoc_options: []
46
46
  require_paths:
47
47
  - lib
@@ -57,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
57
  version: '0'
58
58
  requirements: []
59
59
  rubygems_version: 3.1.2
60
- signing_key:
60
+ signing_key:
61
61
  specification_version: 4
62
62
  summary: Efficient and thread-safe constant autoloader
63
63
  test_files: []