module Zeitwerk::Loader::Helpers

def cdef?(parent, cname)

@sig (Module, Symbol) -> bool
def cdef?(parent, cname)
.const_defined?(cname, false)

def cget(parent, cname)

Raises:
  • (NameError) -
def cget(parent, cname)
.const_get(cname, false)

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 cpath(parent, cname)

frozen object, so we may save a few string allocations.
Symbol#name was introduced in Ruby 3.0. It returns always the same
def cpath(parent, cname)
 == parent ? cname.name : "#{real_mod_name(parent)}::#{cname.name}"

def cpath(parent, cname)

def cpath(parent, cname)
 == parent ? cname.to_s : "#{real_mod_name(parent)}::#{cname}"

def crem(parent, cname)

Raises:
  • (NameError) -
def crem(parent, cname)
.__send__(:remove_const, cname)

def dir?(path)

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

def has_at_least_one_ruby_file?(dir)

@sig (String) -> bool
def has_at_least_one_ruby_file?(dir)
it = [dir]
dir = to_visit.shift
ir) do |_basename, abspath|
 dir?(abspath)
to_visit << abspath
se
return true
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)
xt if !has_at_least_one_ruby_file?(abspath)

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

def ruby?(path)

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

def strict_autoload_path(parent, cname)

def strict_autoload_path(parent, cname)
.autoload?(cname) if cdef?(parent, cname)

def strict_autoload_path(parent, cname)

def strict_autoload_path(parent, cname)
.autoload?(cname, false)

def walk_up(abspath)

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