module Zeitwerk::Loader::Helpers

Constants

CNAME_VALIDATOR

Public Instance Methods

cpath(parent, cname) click to toggle source
# File lib/zeitwerk/loader/helpers.rb, line 118
        def cpath(parent, cname)
  Object == parent ? cname.name : "#{real_mod_name(parent)}::#{cname.name}"
end
strict_autoload_path(parent, cname) click to toggle source
# File lib/zeitwerk/loader/helpers.rb, line 105
        def strict_autoload_path(parent, cname)
  parent.autoload?(cname) if cdef?(parent, cname)
end

Private Instance Methods

cdef?(parent, cname) click to toggle source

@sig (Module, Symbol) -> bool

# File lib/zeitwerk/loader/helpers.rb, line 128
        def cdef?(parent, cname)
  parent.const_defined?(cname, false)
end
cget(parent, cname) click to toggle source

@raise [NameError] @sig (Module, Symbol) -> Object

# File lib/zeitwerk/loader/helpers.rb, line 134
        def cget(parent, cname)
  parent.const_get(cname, false)
end
cname_for(basename, abspath) click to toggle source

@raise [Zeitwerk::NameError] @sig (String, String) -> Symbol

# File lib/zeitwerk/loader/helpers.rb, line 149
          def cname_for(basename, abspath)
    cname = inflector.camelize(basename, abspath)

    unless cname.is_a?(String)
      raise TypeError, "#{inflector.class}#camelize must return a String, received #{cname.inspect}"
    end

    if cname.include?("::")
      raise Zeitwerk::NameError.new(<<~MESSAGE, cname)
        wrong constant name #{cname} inferred by #{inflector.class} from

          #{abspath}

        #{inflector.class}#camelize should return a simple constant name without "::"
      MESSAGE
    end

    begin
      CNAME_VALIDATOR.const_defined?(cname, false)
    rescue ::NameError => error
      path_type = ruby?(abspath) ? "file" : "directory"

      raise Zeitwerk::NameError.new(<<~MESSAGE, error.name)
        #{error.message} inferred by #{inflector.class} from #{path_type}

          #{abspath}

        Possible 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.
      MESSAGE
    end

    cname.to_sym
  end
crem(parent, cname) click to toggle source

@raise [NameError] @sig (Module, Symbol) -> Object

# File lib/zeitwerk/loader/helpers.rb, line 140
        def crem(parent, cname)
  parent.__send__(:remove_const, cname)
end
dir?(path) click to toggle source

@sig (String) -> bool

# File lib/zeitwerk/loader/helpers.rb, line 67
        def dir?(path)
  File.directory?(path)
end
has_at_least_one_ruby_file?(dir) click to toggle source

@sig (String) -> bool

# File lib/zeitwerk/loader/helpers.rb, line 45
        def has_at_least_one_ruby_file?(dir)
  to_visit = [dir]

  while dir = to_visit.shift
    ls(dir) do |_basename, abspath|
      if dir?(abspath)
        to_visit << abspath
      else
        return true
      end
    end
  end

  false
end
hidden?(basename) click to toggle source

@sig (String) -> bool

# File lib/zeitwerk/loader/helpers.rb, line 72
        def hidden?(basename)
  basename.start_with?(".")
end
log(message) click to toggle source

@sig (String) -> void

# File lib/zeitwerk/loader/helpers.rb, line 7
        def log(message)
  method_name = logger.respond_to?(:debug) ? :debug : :call
  logger.send(method_name, "Zeitwerk@#{tag}: #{message}")
end
ls(dir) { |basename, freeze| ... } click to toggle source

@sig (String) { (String, String) -> void } -> void

# File lib/zeitwerk/loader/helpers.rb, line 15
        def ls(dir)
  children = Dir.children(dir)

  # The order in which a directory is listed depends on the file system.
  #
  # Since client code may run in different platforms, it seems convenient to
  # order directory entries. This provides consistent eager loading across
  # platforms, for example.
  children.sort!

  children.each do |basename|
    next if hidden?(basename)

    abspath = File.join(dir, basename)
    next if ignored_path?(abspath)

    if dir?(abspath)
      next if roots.key?(abspath)
      next if !has_at_least_one_ruby_file?(abspath)
    else
      next unless ruby?(abspath)
    end

    # We freeze abspath because that saves allocations when passed later to
    # File methods. See #125.
    yield basename, abspath.freeze
  end
end
ruby?(path) click to toggle source

@sig (String) -> bool

# File lib/zeitwerk/loader/helpers.rb, line 62
        def ruby?(path)
  path.end_with?(".rb")
end
walk_up(abspath) { |abspath| ... } click to toggle source

@sig (String) { (String) -> void } -> void

# File lib/zeitwerk/loader/helpers.rb, line 77
        def walk_up(abspath)
  loop do
    yield abspath
    abspath, basename = File.split(abspath)
    break if basename == "/"
  end
end