zeitwerk 2.4.0 → 2.4.1

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: 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: []