zeitwerk 2.1.0 → 2.1.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: 2af29bb519da160c83620c23a1f1c119c7b534a3e3db308b2635b344b435dfa1
4
- data.tar.gz: ec2dc810c74887befea3550b3305b0b096610cbb06a2983dad0c041c9bed34dc
3
+ metadata.gz: 346ac927810dc8ce5b206e4d90e3db572328fa500039ad4af19144bd2d193c0b
4
+ data.tar.gz: ca4c317c9acfc26898260ae331da60a1bbd6d2c384556fb15d205487936feeb2
5
5
  SHA512:
6
- metadata.gz: 8cafd96d9f21546ea8dcb58f8b589d59b5de994492a2f89f6cd4eb2701d673e58c888884b672ddd47580778090f4af918c908e6325d5690ce8297b0e152eb391
7
- data.tar.gz: e1fba9ebf4e35fa10c2577bdb4a19124ee26e3d09a85b2382a5bc0c83688130b14a0c8e9900e6572f25efe86c388b54139d9ca82d7053cfc415b39a618d1ec16
6
+ metadata.gz: f4e98230152289f2a52dae3fd4de94c25436325eade87cbd46bf78b60cc4f2480907a3ad19def25a15c6e8d07ed92b4e324244e17513c891648ac5fb31a0cb84
7
+ data.tar.gz: ea6f69fe9463d847dfbf790ee6dbf22b5574b4bbb473f4acd998a58e905fc2aeb103ec5988f79fd8eaa0a7f641d6c10f428c06e53d526c2a0fe5456a2f5426a1
@@ -53,19 +53,21 @@ module Zeitwerk
53
53
  # @return [Set<String>]
54
54
  attr_reader :ignored_paths
55
55
 
56
- # Keeps track of shadowed files.
56
+ # A _shadowed file_ is a file managed by this loader that is ignored when
57
+ # setting autoloads because its matching constant is taken. Either the
58
+ # constant is already defined, or there exists an autoload for it.
57
59
  #
58
- # A shadowed file is a file managed by this autoloader that is skipped
59
- # because its matching constant path has already been seen. Think $LOAD_PATH
60
- # and require, only the first occurrence of a given relative name is loaded.
60
+ # Think $LOAD_PATH and require, only the first occurrence of a given
61
+ # relative name is loaded.
61
62
  #
62
- # If the existing occurrence is an autoload, we map the file name to the
63
- # shadowing autoload path. If the existing occurrence is an already defined
64
- # constant, the file name is mapped to the constant path, meaning it was
65
- # loaded elsewhere.
63
+ # This set keeps track of the absolute path of shadowed files, to be able to
64
+ # skip them while eager loading.
65
+ #
66
+ # Note this cannot be implemented with do_not_eager_load because these
67
+ # files are not autoloadable.
66
68
  #
67
69
  # @private
68
- # @return [{String => String}]
70
+ # @return [Set<String>]
69
71
  attr_reader :shadowed_files
70
72
 
71
73
  # Maps real absolute paths for which an autoload has been set ---and not
@@ -145,7 +147,7 @@ module Zeitwerk
145
147
  @autoloaded_dirs = []
146
148
  @to_unload = {}
147
149
  @lazy_subdirs = {}
148
- @shadowed_files = {}
150
+ @shadowed_files = Set.new
149
151
  @eager_load_exclusions = Set.new
150
152
 
151
153
  # TODO: find a better name for these mutexes.
@@ -352,13 +354,15 @@ module Zeitwerk
352
354
  next if eager_load_exclusions.member?(abspath)
353
355
 
354
356
  if ruby?(abspath)
355
- require abspath unless shadowed_files.key?(abspath)
357
+ require abspath unless shadowed_files.member?(abspath)
356
358
  elsif dir?(abspath)
357
359
  queue << abspath
358
360
  end
359
361
  end
360
362
  end
361
363
 
364
+ shadowed_files.clear
365
+
362
366
  autoloaded_dirs.each do |dir|
363
367
  Registry.unregister_autoload(dir)
364
368
  end
@@ -488,22 +492,38 @@ module Zeitwerk
488
492
  def autoload_file(parent, cname, file)
489
493
  if autoload_path = autoload_for?(parent, cname)
490
494
  # First autoload for a Ruby file wins, just ignore subsequent ones.
491
- shadowed_files[file] = autoload_path and return if ruby?(autoload_path)
492
-
493
- # Override autovivification, we want the namespace to become the
494
- # class/module defined in this file.
495
- autoloads.delete(autoload_path)
496
- Registry.unregister_autoload(autoload_path)
497
-
498
- set_autoload(parent, cname, file)
499
- register_explicit_namespace(cpath(parent, cname))
495
+ if ruby?(autoload_path)
496
+ log("file #{file} is ignored because #{autoload_path} has precedence") if logger
497
+ shadowed_files.add(file)
498
+ else
499
+ promote_namespace_from_implicit_to_explicit(
500
+ dir: autoload_path,
501
+ file: file,
502
+ parent: parent,
503
+ cname: cname
504
+ )
505
+ end
500
506
  elsif cdef?(parent, cname)
501
- shadowed_files[file] = cpath(parent, cname)
507
+ log("file #{file} is ignored because #{cpath(parent, cname)} is already defined") if logger
508
+ shadowed_files.add(file)
502
509
  else
503
510
  set_autoload(parent, cname, file)
504
511
  end
505
512
  end
506
513
 
514
+ # @param dir [String] directory that would have autovivified a module
515
+ # @param file [String] the file where the namespace is explictly defined
516
+ # @param parent [Module]
517
+ # @param cname [String]
518
+ # @return [void]
519
+ def promote_namespace_from_implicit_to_explicit(dir:, file:, parent:, cname:)
520
+ autoloads.delete(dir)
521
+ Registry.unregister_autoload(dir)
522
+
523
+ set_autoload(parent, cname, file)
524
+ register_explicit_namespace(cpath(parent, cname))
525
+ end
526
+
507
527
  # @param parent [Module]
508
528
  # @param cname [String]
509
529
  # @param abspath [String]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zeitwerk
4
- VERSION = "2.1.0"
4
+ VERSION = "2.1.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.1.0
4
+ version: 2.1.1
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-04-09 00:00:00.000000000 Z
11
+ date: 2019-04-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  Zeitwerk implements constant autoloading with Ruby semantics. Each gem