zeitwerk 2.7.5 → 2.8.0
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 +131 -71
- data/lib/zeitwerk/core_ext/kernel.rb +1 -1
- data/lib/zeitwerk/cref/map.rb +1 -1
- data/lib/zeitwerk/cref.rb +8 -1
- data/lib/zeitwerk/error.rb +12 -1
- data/lib/zeitwerk/gem_inflector.rb +3 -3
- data/lib/zeitwerk/gem_loader.rb +4 -4
- data/lib/zeitwerk/inflector.rb +8 -8
- data/lib/zeitwerk/loader/callbacks.rb +1 -1
- data/lib/zeitwerk/loader/config.rb +64 -18
- data/lib/zeitwerk/loader/eager_load.rb +23 -27
- data/lib/zeitwerk/loader/file_system.rb +72 -25
- data/lib/zeitwerk/loader/helpers.rb +2 -2
- data/lib/zeitwerk/loader.rb +164 -126
- data/lib/zeitwerk/registry.rb +6 -6
- data/lib/zeitwerk/version.rb +1 -1
- data/lib/zeitwerk.rb +13 -13
- metadata +1 -1
data/lib/zeitwerk/loader.rb
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'monitor'
|
|
4
|
+
require 'set'
|
|
5
5
|
|
|
6
6
|
module Zeitwerk
|
|
7
7
|
class Loader
|
|
8
|
-
require_relative
|
|
9
|
-
require_relative
|
|
10
|
-
require_relative
|
|
11
|
-
require_relative
|
|
12
|
-
require_relative
|
|
8
|
+
require_relative 'loader/helpers'
|
|
9
|
+
require_relative 'loader/callbacks'
|
|
10
|
+
require_relative 'loader/config'
|
|
11
|
+
require_relative 'loader/eager_load'
|
|
12
|
+
require_relative 'loader/file_system'
|
|
13
13
|
|
|
14
14
|
extend Internal
|
|
15
15
|
|
|
@@ -22,8 +22,8 @@ module Zeitwerk
|
|
|
22
22
|
# Maps absolute paths for which an autoload has been set ---and not
|
|
23
23
|
# executed--- to their corresponding Zeitwerk::Cref object.
|
|
24
24
|
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
25
|
+
# '/Users/fxn/blog/app/models/user.rb' => #<Zeitwerk::Cref:... @mod=Object, @cname=:User, ...>,
|
|
26
|
+
# '/Users/fxn/blog/app/models/hotel/pricing.rb' => #<Zeitwerk::Cref:... @mod=Hotel, @cname=:Pricing, ...>,
|
|
27
27
|
# ...
|
|
28
28
|
#
|
|
29
29
|
#: Hash[String, Zeitwerk::Cref]
|
|
@@ -102,6 +102,7 @@ module Zeitwerk
|
|
|
102
102
|
attr_reader :dirs_autoload_monitor
|
|
103
103
|
private :dirs_autoload_monitor
|
|
104
104
|
|
|
105
|
+
#: () -> void
|
|
105
106
|
def initialize
|
|
106
107
|
super
|
|
107
108
|
|
|
@@ -129,7 +130,7 @@ module Zeitwerk
|
|
|
129
130
|
break if @setup
|
|
130
131
|
|
|
131
132
|
actual_roots.each do |root_dir, root_namespace|
|
|
132
|
-
define_autoloads_for_dir(root_dir, root_namespace)
|
|
133
|
+
define_autoloads_for_dir(root_dir, root_namespace, external: true)
|
|
133
134
|
end
|
|
134
135
|
|
|
135
136
|
on_setup_callbacks.each(&:call)
|
|
@@ -153,73 +154,79 @@ module Zeitwerk
|
|
|
153
154
|
def unload
|
|
154
155
|
mutex.synchronize do
|
|
155
156
|
raise SetupRequired unless @setup
|
|
157
|
+
__unload
|
|
158
|
+
end
|
|
159
|
+
end
|
|
156
160
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
else
|
|
169
|
-
# Could happen if loaded with require_relative. That is unsupported,
|
|
170
|
-
# and the constant path would escape unloadable_cpath? This is just
|
|
171
|
-
# defensive code to clean things up as much as we are able to.
|
|
172
|
-
unload_cref(cref)
|
|
173
|
-
unloaded_files.add(abspath) if @fs.rb_extension?(abspath)
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
to_unload.each do |abspath, cref|
|
|
178
|
-
unless on_unload_callbacks.empty?
|
|
179
|
-
begin
|
|
180
|
-
value = cref.get
|
|
181
|
-
rescue ::NameError
|
|
182
|
-
# Perhaps the user deleted the constant by hand, or perhaps an
|
|
183
|
-
# autoload failed to define the expected constant but the user
|
|
184
|
-
# rescued the exception.
|
|
185
|
-
else
|
|
186
|
-
run_on_unload_callbacks(cref, value, abspath)
|
|
187
|
-
end
|
|
188
|
-
end
|
|
161
|
+
# This is an internal method.
|
|
162
|
+
#
|
|
163
|
+
#: () -> void
|
|
164
|
+
def __unload
|
|
165
|
+
# We are going to keep track of the files that were required by our
|
|
166
|
+
# autoloads to later remove them from $LOADED_FEATURES, thus making them
|
|
167
|
+
# loadable by Kernel#require again.
|
|
168
|
+
#
|
|
169
|
+
# Directories are not stored in $LOADED_FEATURES, keeping track of files
|
|
170
|
+
# is enough.
|
|
171
|
+
unloaded_files = Set.new
|
|
189
172
|
|
|
173
|
+
autoloads.each do |abspath, cref|
|
|
174
|
+
if cref.autoload?
|
|
175
|
+
unload_autoload(cref)
|
|
176
|
+
else
|
|
177
|
+
# Could happen if loaded with require_relative. That is unsupported,
|
|
178
|
+
# and the constant path would escape unloadable_cpath? This is just
|
|
179
|
+
# defensive code to clean things up as much as we are able to.
|
|
190
180
|
unload_cref(cref)
|
|
191
181
|
unloaded_files.add(abspath) if @fs.rb_extension?(abspath)
|
|
192
182
|
end
|
|
183
|
+
end
|
|
193
184
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
# one of those methods.
|
|
206
|
-
$LOADED_FEATURES.reject! { |file| unloaded_files.member?(file) }
|
|
185
|
+
to_unload.each do |abspath, cref|
|
|
186
|
+
unless on_unload_callbacks.empty?
|
|
187
|
+
begin
|
|
188
|
+
value = cref.get
|
|
189
|
+
rescue ::NameError
|
|
190
|
+
# Perhaps the user deleted the constant by hand, or perhaps an
|
|
191
|
+
# autoload failed to define the expected constant but the user
|
|
192
|
+
# rescued the exception.
|
|
193
|
+
else
|
|
194
|
+
run_on_unload_callbacks(cref, value, abspath)
|
|
195
|
+
end
|
|
207
196
|
end
|
|
208
197
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
namespace_dirs.clear
|
|
213
|
-
shadowed_files.clear
|
|
198
|
+
unload_cref(cref)
|
|
199
|
+
unloaded_files.add(abspath) if @fs.rb_extension?(abspath)
|
|
200
|
+
end
|
|
214
201
|
|
|
215
|
-
|
|
216
|
-
|
|
202
|
+
unless unloaded_files.empty?
|
|
203
|
+
# Bootsnap decorates Kernel#require to speed it up using a cache and
|
|
204
|
+
# this optimization does not check if $LOADED_FEATURES has the file.
|
|
205
|
+
#
|
|
206
|
+
# To make it aware of changes, the gem defines singleton methods in
|
|
207
|
+
# $LOADED_FEATURES:
|
|
208
|
+
#
|
|
209
|
+
# https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb
|
|
210
|
+
#
|
|
211
|
+
# Rails applications may depend on bootsnap, so for unloading to work
|
|
212
|
+
# in that setting it is preferable that we restrict our API choice to
|
|
213
|
+
# one of those methods.
|
|
214
|
+
$LOADED_FEATURES.reject! { |file| unloaded_files.member?(file) }
|
|
215
|
+
end
|
|
217
216
|
|
|
218
|
-
|
|
217
|
+
autoloads.clear
|
|
218
|
+
autoloaded_dirs.clear
|
|
219
|
+
to_unload.clear
|
|
220
|
+
namespace_dirs.clear
|
|
221
|
+
shadowed_files.clear
|
|
219
222
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
+
unregister_inceptions
|
|
224
|
+
unregister_explicit_namespaces
|
|
225
|
+
|
|
226
|
+
Registry.autoloads.unregister_loader(self)
|
|
227
|
+
|
|
228
|
+
@setup = false
|
|
229
|
+
@eager_loaded = false
|
|
223
230
|
end
|
|
224
231
|
|
|
225
232
|
# Unloads all loaded code, and calls setup again so that the loader is able
|
|
@@ -234,8 +241,11 @@ module Zeitwerk
|
|
|
234
241
|
raise SetupRequired unless @setup
|
|
235
242
|
|
|
236
243
|
unload
|
|
244
|
+
|
|
237
245
|
recompute_ignored_paths
|
|
238
246
|
recompute_collapse_dirs
|
|
247
|
+
recompute_collapse_parents
|
|
248
|
+
|
|
239
249
|
setup
|
|
240
250
|
end
|
|
241
251
|
|
|
@@ -252,18 +262,20 @@ module Zeitwerk
|
|
|
252
262
|
while (dir, cpath = queue.shift)
|
|
253
263
|
result[dir] = cpath
|
|
254
264
|
|
|
255
|
-
prefix = cpath ==
|
|
265
|
+
prefix = cpath == 'Object' ? '' : cpath + '::'
|
|
256
266
|
|
|
257
|
-
@fs.ls(dir) do |basename, abspath, ftype|
|
|
267
|
+
@fs.ls(dir, collapse: false) do |basename, abspath, ftype|
|
|
258
268
|
if ftype == :file
|
|
259
|
-
basename
|
|
260
|
-
|
|
261
|
-
else
|
|
262
|
-
if collapse?(abspath)
|
|
263
|
-
queue << [abspath, cpath]
|
|
269
|
+
if basename == @nsfile
|
|
270
|
+
result[abspath] = cpath
|
|
264
271
|
else
|
|
265
|
-
|
|
272
|
+
basename.delete_suffix!('.rb')
|
|
273
|
+
result[abspath] = "#{prefix}#{cname_for(basename, abspath)}"
|
|
266
274
|
end
|
|
275
|
+
elsif collapse?(abspath)
|
|
276
|
+
queue.unshift([abspath, cpath])
|
|
277
|
+
else
|
|
278
|
+
queue.push([abspath, "#{prefix}#{cname_for(basename, abspath)}"])
|
|
267
279
|
end
|
|
268
280
|
end
|
|
269
281
|
end
|
|
@@ -285,11 +297,11 @@ module Zeitwerk
|
|
|
285
297
|
|
|
286
298
|
paths = []
|
|
287
299
|
|
|
288
|
-
if
|
|
289
|
-
basename = File.basename(abspath
|
|
300
|
+
if ftype == :file
|
|
301
|
+
basename = File.basename(abspath)
|
|
290
302
|
return if @fs.hidden?(basename)
|
|
291
303
|
|
|
292
|
-
paths << [basename, abspath]
|
|
304
|
+
paths << [basename.delete_suffix('.rb'), abspath] unless basename == @nsfile
|
|
293
305
|
walk_up_from = File.dirname(abspath)
|
|
294
306
|
else
|
|
295
307
|
walk_up_from = abspath
|
|
@@ -315,9 +327,9 @@ module Zeitwerk
|
|
|
315
327
|
cnames = paths.reverse_each.map { cname_for(_1, _2) }
|
|
316
328
|
|
|
317
329
|
if root_namespace == Object
|
|
318
|
-
cnames.join(
|
|
330
|
+
cnames.join('::')
|
|
319
331
|
else
|
|
320
|
-
"#{real_mod_name(root_namespace)}::#{cnames.join(
|
|
332
|
+
"#{real_mod_name(root_namespace)}::#{cnames.join('::')}"
|
|
321
333
|
end
|
|
322
334
|
end
|
|
323
335
|
end
|
|
@@ -384,10 +396,10 @@ module Zeitwerk
|
|
|
384
396
|
|
|
385
397
|
# This is a shortcut for
|
|
386
398
|
#
|
|
387
|
-
# require
|
|
399
|
+
# require 'zeitwerk'
|
|
388
400
|
#
|
|
389
401
|
# loader = Zeitwerk::Loader.new
|
|
390
|
-
# loader.tag = File.basename(__FILE__,
|
|
402
|
+
# loader.tag = File.basename(__FILE__, '.rb')
|
|
391
403
|
# loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
|
|
392
404
|
# loader.push_dir(__dir__)
|
|
393
405
|
#
|
|
@@ -405,10 +417,10 @@ module Zeitwerk
|
|
|
405
417
|
|
|
406
418
|
# This is a shortcut for
|
|
407
419
|
#
|
|
408
|
-
# require
|
|
420
|
+
# require 'zeitwerk'
|
|
409
421
|
#
|
|
410
422
|
# loader = Zeitwerk::Loader.new
|
|
411
|
-
# loader.tag = namespace.name +
|
|
423
|
+
# loader.tag = namespace.name + '-' + File.basename(__FILE__, '.rb')
|
|
412
424
|
# loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
|
|
413
425
|
# loader.push_dir(__dir__, namespace: namespace)
|
|
414
426
|
#
|
|
@@ -425,7 +437,7 @@ module Zeitwerk
|
|
|
425
437
|
end
|
|
426
438
|
|
|
427
439
|
unless real_mod_name(namespace)
|
|
428
|
-
raise Zeitwerk::Error,
|
|
440
|
+
raise Zeitwerk::Error, 'extending anonymous namespaces is unsupported'
|
|
429
441
|
end
|
|
430
442
|
|
|
431
443
|
called_from = caller_locations(1, 1).first.path
|
|
@@ -473,68 +485,94 @@ module Zeitwerk
|
|
|
473
485
|
end
|
|
474
486
|
end
|
|
475
487
|
|
|
476
|
-
|
|
477
|
-
|
|
488
|
+
# Scans `dir` and sets autoloads in `mod` for the constants its contents are
|
|
489
|
+
# expected to define.
|
|
490
|
+
#
|
|
491
|
+
# The `external` flag indicates whether `mod` has been externally defined,
|
|
492
|
+
# as is the case with root namespaces or reopened third-party namespaces.
|
|
493
|
+
#
|
|
494
|
+
#: (String, Module, external: boolish) -> void
|
|
495
|
+
private def define_autoloads_for_dir(dir, mod, external:)
|
|
478
496
|
@fs.ls(dir) do |basename, abspath, ftype|
|
|
479
497
|
if ftype == :file
|
|
480
|
-
basename
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
autoload_subdir(cref, abspath)
|
|
498
|
+
if basename == @nsfile
|
|
499
|
+
if external
|
|
500
|
+
cpath = real_mod_name(mod)
|
|
501
|
+
location = Object.const_source_location(cpath)&.join(':')
|
|
502
|
+
location = nil if location&.empty?
|
|
503
|
+
raise Zeitwerk::ConflictingNamespaceDefinitionError.new(cpath, location: location, conflicting_file: abspath)
|
|
504
|
+
end
|
|
505
|
+
next # Pass if this is a managed namespace, the nsfile was already probed when visiting the parent directory.
|
|
489
506
|
end
|
|
507
|
+
|
|
508
|
+
basename.delete_suffix!('.rb')
|
|
509
|
+
cref = Cref.new(mod, cname_for(basename, abspath))
|
|
510
|
+
visit_file(cref, abspath)
|
|
511
|
+
else
|
|
512
|
+
cref = Cref.new(mod, cname_for(basename, abspath))
|
|
513
|
+
visit_subdir(cref, abspath, external:)
|
|
490
514
|
end
|
|
491
515
|
end
|
|
492
516
|
end
|
|
493
517
|
|
|
494
518
|
#: (Zeitwerk::Cref, String) -> void
|
|
495
|
-
private def
|
|
519
|
+
private def visit_file(cref, file)
|
|
520
|
+
if autoload_path = cref.autoload? || Registry.inceptions.registered?(cref)
|
|
521
|
+
if @fs.rb_extension?(autoload_path)
|
|
522
|
+
if File.basename(autoload_path) == @nsfile && autoload_path_set_by_me_for?(cref)
|
|
523
|
+
raise Zeitwerk::ConflictingNamespaceDefinitionError.new(cref.path, location: autoload_path, conflicting_file: file)
|
|
524
|
+
end
|
|
525
|
+
shadowed_files << file
|
|
526
|
+
log { "file #{file} is ignored because #{autoload_path} has precedence" }
|
|
527
|
+
else
|
|
528
|
+
promote_namespace_from_implicit_to_explicit(dir: autoload_path, file: file, cref: cref)
|
|
529
|
+
end
|
|
530
|
+
elsif cref.defined?
|
|
531
|
+
shadowed_files << file
|
|
532
|
+
if location = cref.location
|
|
533
|
+
log { "file #{file} is ignored because #{cref} is already defined in #{location}" }
|
|
534
|
+
else
|
|
535
|
+
log { "file #{file} is ignored because #{cref} is already defined (unknown location)" }
|
|
536
|
+
end
|
|
537
|
+
else
|
|
538
|
+
define_autoload(cref, file)
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
#: (Zeitwerk::Cref, String, external: boolish) -> void
|
|
543
|
+
private def visit_subdir(cref, subdir, external:)
|
|
496
544
|
if autoload_path = autoload_path_set_by_me_for?(cref)
|
|
497
545
|
if @fs.rb_extension?(autoload_path)
|
|
546
|
+
# The namespace that corresponds to this subdirectory is defined in a
|
|
547
|
+
# file, either regular or nsfile. Therefore, a nsfile would be a
|
|
548
|
+
# duplication.
|
|
549
|
+
if nsfile_abspath = @fs.has_exactly_one_nsfile?(cref, subdir)
|
|
550
|
+
raise Zeitwerk::ConflictingNamespaceDefinitionError.new(cref.path, location: autoload_path, conflicting_file: nsfile_abspath)
|
|
551
|
+
end
|
|
498
552
|
# Scanning visited a Ruby file first, and now a directory for the same
|
|
499
|
-
# constant has been found. This
|
|
500
|
-
# namespace whose definition was seen first.
|
|
553
|
+
# constant has been found. This is an explicit namespace.
|
|
501
554
|
#
|
|
502
|
-
#
|
|
503
|
-
#
|
|
504
|
-
# on, no big deal.
|
|
555
|
+
# The namespace may be spread over multiple directories and perhaps it
|
|
556
|
+
# was already registered, but registering is idempotent, just do it.
|
|
505
557
|
register_explicit_namespace(cref)
|
|
558
|
+
elsif nsfile_abspath = @fs.has_exactly_one_nsfile?(cref, subdir)
|
|
559
|
+
# Scanning found a matching directory first, and now we saw a nsfile.
|
|
560
|
+
promote_namespace_from_implicit_to_explicit(dir: subdir, file: nsfile_abspath, cref: cref)
|
|
506
561
|
end
|
|
507
|
-
# If the existing autoload points to a file, it has to be preserved, if
|
|
508
|
-
# not, it is fine as it is. In either case, we do not need to override.
|
|
509
|
-
# Just remember the subdirectory conforms this namespace.
|
|
510
562
|
namespace_dirs.get_or_set(cref) { [] } << subdir
|
|
511
563
|
elsif !cref.defined?
|
|
512
|
-
|
|
564
|
+
if nsfile_abspath = @fs.has_exactly_one_nsfile?(cref, subdir)
|
|
565
|
+
define_autoload(cref, nsfile_abspath)
|
|
566
|
+
register_explicit_namespace(cref)
|
|
567
|
+
else
|
|
568
|
+
define_autoload(cref, subdir)
|
|
569
|
+
end
|
|
513
570
|
namespace_dirs.get_or_set(cref) { [] } << subdir
|
|
514
|
-
define_autoload(cref, subdir)
|
|
515
571
|
else
|
|
516
572
|
# For whatever reason the constant that corresponds to this namespace has
|
|
517
573
|
# already been defined, we have to recurse.
|
|
518
574
|
log { "the namespace #{cref} already exists, descending into #{subdir}" }
|
|
519
|
-
define_autoloads_for_dir(subdir, cref.get)
|
|
520
|
-
end
|
|
521
|
-
end
|
|
522
|
-
|
|
523
|
-
#: (Zeitwerk::Cref, String) -> void
|
|
524
|
-
private def autoload_file(cref, file)
|
|
525
|
-
if autoload_path = cref.autoload? || Registry.inceptions.registered?(cref)
|
|
526
|
-
# First autoload for a Ruby file wins, just ignore subsequent ones.
|
|
527
|
-
if @fs.rb_extension?(autoload_path)
|
|
528
|
-
shadowed_files << file
|
|
529
|
-
log { "file #{file} is ignored because #{autoload_path} has precedence" }
|
|
530
|
-
else
|
|
531
|
-
promote_namespace_from_implicit_to_explicit(dir: autoload_path, file: file, cref: cref)
|
|
532
|
-
end
|
|
533
|
-
elsif cref.defined?
|
|
534
|
-
shadowed_files << file
|
|
535
|
-
log { "file #{file} is ignored because #{cref} is already defined" }
|
|
536
|
-
else
|
|
537
|
-
define_autoload(cref, file)
|
|
575
|
+
define_autoloads_for_dir(subdir, cref.get, external:)
|
|
538
576
|
end
|
|
539
577
|
end
|
|
540
578
|
|
|
@@ -608,7 +646,7 @@ module Zeitwerk
|
|
|
608
646
|
#: (String) -> void
|
|
609
647
|
private def raise_if_conflicting_root_dir(root_dir)
|
|
610
648
|
if loader = Registry.conflicting_root_dir?(self, root_dir)
|
|
611
|
-
require
|
|
649
|
+
require 'pp' # Needed to have pretty_inspect available.
|
|
612
650
|
raise Error,
|
|
613
651
|
"loader\n\n#{pretty_inspect}\n\nwants to manage directory #{root_dir}," \
|
|
614
652
|
" which is already managed by\n\n#{loader.pretty_inspect}\n"
|
data/lib/zeitwerk/registry.rb
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Zeitwerk
|
|
4
4
|
module Registry # :nodoc: all
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
5
|
+
require_relative 'registry/autoloads'
|
|
6
|
+
require_relative 'registry/explicit_namespaces'
|
|
7
|
+
require_relative 'registry/inceptions'
|
|
8
|
+
require_relative 'registry/loaders'
|
|
9
9
|
|
|
10
10
|
class << self
|
|
11
11
|
# Keeps track of all loaders. Useful to broadcast messages and to prevent
|
|
@@ -54,8 +54,8 @@ module Zeitwerk
|
|
|
54
54
|
# Conflicting directories are rare, optimize for the common case.
|
|
55
55
|
next if !new_root_dir.start_with?(existing_root_dir) && !existing_root_dir.start_with?(new_root_dir)
|
|
56
56
|
|
|
57
|
-
new_root_dir_slash = new_root_dir +
|
|
58
|
-
existing_root_dir_slash = existing_root_dir +
|
|
57
|
+
new_root_dir_slash = new_root_dir + '/'
|
|
58
|
+
existing_root_dir_slash = existing_root_dir + '/'
|
|
59
59
|
next if !new_root_dir_slash.start_with?(existing_root_dir_slash) && !existing_root_dir_slash.start_with?(new_root_dir_slash)
|
|
60
60
|
|
|
61
61
|
next if loader.__ignores?(existing_root_dir)
|
data/lib/zeitwerk/version.rb
CHANGED
data/lib/zeitwerk.rb
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Zeitwerk
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
9
|
-
require_relative
|
|
10
|
-
require_relative
|
|
11
|
-
require_relative
|
|
12
|
-
require_relative
|
|
13
|
-
require_relative
|
|
14
|
-
require_relative
|
|
4
|
+
require_relative 'zeitwerk/real_mod_name'
|
|
5
|
+
require_relative 'zeitwerk/internal'
|
|
6
|
+
require_relative 'zeitwerk/cref'
|
|
7
|
+
require_relative 'zeitwerk/loader'
|
|
8
|
+
require_relative 'zeitwerk/gem_loader'
|
|
9
|
+
require_relative 'zeitwerk/registry'
|
|
10
|
+
require_relative 'zeitwerk/inflector'
|
|
11
|
+
require_relative 'zeitwerk/gem_inflector'
|
|
12
|
+
require_relative 'zeitwerk/null_inflector'
|
|
13
|
+
require_relative 'zeitwerk/error'
|
|
14
|
+
require_relative 'zeitwerk/version'
|
|
15
15
|
|
|
16
|
-
require_relative
|
|
17
|
-
require_relative
|
|
16
|
+
require_relative 'zeitwerk/core_ext/kernel'
|
|
17
|
+
require_relative 'zeitwerk/core_ext/module'
|
|
18
18
|
|
|
19
19
|
# This is a dangerous method.
|
|
20
20
|
#
|