module Zeitwerk::Loader::Helpers

def cname_for(basename, abspath)

Raises:
  • (Zeitwerk::NameError) -
def cname_for(basename, abspath)
= inflector.camelize(basename, abspath)
 cname.is_a?(String)
e TypeError, "#{inflector.class}#camelize must return a String, received #{cname.inspect}"
me.include?("::")
e Zeitwerk::NameError.new(<<~MESSAGE, cname)
ong constant name #{cname} inferred by #{inflector.class} from
#{abspath}
inflector.class}#camelize should return a simple constant name without "::"
AGE
E_VALIDATOR.const_defined?(cname, false)
 ::NameError => error
_type = ruby?(abspath) ? "file" : "directory"
e Zeitwerk::NameError.new(<<~MESSAGE, error.name)
error.message} inferred by #{inflector.class} from #{path_type}
#{abspath}
ssible ways to address this:
* Tell Zeitwerk to ignore this particular #{path_type}.
* Tell Zeitwerk to ignore one of its parent directories.
* Rename the #{path_type} to comply with the naming conventions.
* Modify the inflector to handle this case.
AGE
to_sym

def dir?(path)

@sig (String) -> bool
def dir?(path)
irectory?(path)

def has_at_least_one_ruby_file?(dir)

@sig (String) -> bool

common case in which there are Ruby files.
important to list as less directories as possible and return fast in the
Looks for a Ruby file using breadth-first search. This type of search is
def has_at_least_one_ruby_file?(dir)
it = [dir]
(dir = to_visit.shift)
dren = Dir.children(dir)
dren.each do |basename|
xt if hidden?(basename)
spath = File.join(dir, basename)
xt if ignored_path?(abspath)
 dir?(abspath)
to_visit << abspath unless roots.key?(abspath)
se
return true if ruby?(abspath)
d

def hidden?(basename)

@sig (String) -> bool
def hidden?(basename)
me.start_with?(".")

def log(message)

@sig (String) -> void
def log(message)
_name = logger.respond_to?(:debug) ? :debug : :call
.send(method_name, "Zeitwerk@#{tag}: #{message}")

def ls(dir)

@sig (String) { (String, String) -> void } -> void
def ls(dir)
en = Dir.children(dir)
order in which a directory is listed depends on the file system.
e client code may run in different platforms, it seems convenient to
r directory entries. This provides consistent eager loading across
forms, for example.
en.sort!
en.each do |basename|
 if hidden?(basename)
ath = File.join(dir, basename)
 if ignored_path?(abspath)
ir?(abspath)
xt if roots.key?(abspath)
 !has_at_least_one_ruby_file?(abspath)
log("directory #{abspath} is ignored because it has no Ruby files") if logger
next
d
ype = :directory

xt unless ruby?(abspath)
ype = :file
 freeze abspath because that saves allocations when passed later to
le methods. See #125.
d basename, abspath.freeze, ftype

def ruby?(path)

@sig (String) -> bool
def ruby?(path)
nd_with?(".rb")

def walk_up(abspath)

@sig (String) { (String) -> void } -> void
def walk_up(abspath)
o
d abspath
ath, basename = File.split(abspath)
k if basename == "/"