Module: Zeitwerk::Loader::EagerLoad
- Included in:
- Zeitwerk::Loader
- Defined in:
- lib/zeitwerk/loader/eager_load.rb
Instance Method Summary collapse
-
#eager_load(force: false) ⇒ Object
Eager loads all files in the root directories, recursively.
- #eager_load_dir(path) ⇒ Object
- #eager_load_namespace(mod) ⇒ Object
-
#load_file(path) ⇒ Object
Loads the given Ruby file.
Instance Method Details
#eager_load(force: false) ⇒ Object
Eager loads all files in the root directories, recursively. Files do not need to be in ‘$LOAD_PATH`, absolute file names are used. Ignored and shadowed files are not eager loaded. You can opt-out specifically in specific files and directories with `do_not_eager_load`, and that can be overridden passing `force: true`.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/zeitwerk/loader/eager_load.rb', line 9 def eager_load(force: false) mutex.synchronize do break if @eager_loaded raise Zeitwerk::SetupRequired unless @setup log("eager load start") if logger actual_roots.each do |root_dir, root_namespace| actual_eager_load_dir(root_dir, root_namespace, force: force) end autoloaded_dirs.each do |autoloaded_dir| Zeitwerk::Registry.unregister_autoload(autoloaded_dir) end autoloaded_dirs.clear @eager_loaded = true log("eager load end") if logger end end |
#eager_load_dir(path) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/zeitwerk/loader/eager_load.rb', line 32 def eager_load_dir(path) raise Zeitwerk::SetupRequired unless @setup abspath = File.(path) raise Zeitwerk::Error.new("#{abspath} is not a directory") unless dir?(abspath) cnames = [] root_namespace = nil walk_up(abspath) do |dir| return if ignored_path?(dir) return if eager_load_exclusions.member?(dir) break if root_namespace = roots[dir] basename = File.basename(dir) return if hidden?(basename) unless collapse?(dir) cnames << inflector.camelize(basename, dir).to_sym end end raise Zeitwerk::Error.new("I do not manage #{abspath}") unless root_namespace return if @eager_loaded namespace = root_namespace cnames.reverse_each do |cname| # Can happen if there are no Ruby files. This is not an error condition, # the directory is actually managed. Could have Ruby files later. return unless namespace.const_defined?(cname, false) namespace = namespace.const_get(cname, false) end # A shortcircuiting test depends on the invocation of this method. Please # keep them in sync if refactored. actual_eager_load_dir(abspath, namespace) end |
#eager_load_namespace(mod) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/zeitwerk/loader/eager_load.rb', line 74 def eager_load_namespace(mod) raise Zeitwerk::SetupRequired unless @setup unless mod.is_a?(Module) raise Zeitwerk::Error, "#{mod.inspect} is not a class or module object" end return if @eager_loaded mod_name = real_mod_name(mod) return unless mod_name actual_roots.each do |root_dir, root_namespace| if Object.equal?(mod) # A shortcircuiting test depends on the invocation of this method. # Please keep them in sync if refactored. actual_eager_load_dir(root_dir, root_namespace) elsif root_namespace.equal?(Object) eager_load_child_namespace(mod, mod_name, root_dir, root_namespace) else root_namespace_name = real_mod_name(root_namespace) if root_namespace_name.start_with?(mod_name + "::") actual_eager_load_dir(root_dir, root_namespace) elsif mod_name == root_namespace_name actual_eager_load_dir(root_dir, root_namespace) elsif mod_name.start_with?(root_namespace_name + "::") eager_load_child_namespace(mod, mod_name, root_dir, root_namespace) else # Unrelated constant hierarchies, do nothing. end end end end |
#load_file(path) ⇒ Object
Loads the given Ruby file.
Raises if the argument is ignored, shadowed, or not managed by the receiver.
The method is implemented as ‘constantize` for files, in a sense, to be able to descend orderly and make sure the file is loadable.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/zeitwerk/loader/eager_load.rb', line 116 def load_file(path) abspath = File.(path) raise Zeitwerk::Error.new("#{abspath} does not exist") unless File.exist?(abspath) raise Zeitwerk::Error.new("#{abspath} is not a Ruby file") if dir?(abspath) || !ruby?(abspath) raise Zeitwerk::Error.new("#{abspath} is ignored") if ignored_path?(abspath) basename = File.basename(abspath, ".rb") raise Zeitwerk::Error.new("#{abspath} is ignored") if hidden?(basename) base_cname = inflector.camelize(basename, abspath).to_sym root_namespace = nil cnames = [] walk_up(File.dirname(abspath)) do |dir| raise Zeitwerk::Error.new("#{abspath} is ignored") if ignored_path?(dir) break if root_namespace = roots[dir] basename = File.basename(dir) raise Zeitwerk::Error.new("#{abspath} is ignored") if hidden?(basename) unless collapse?(dir) cnames << inflector.camelize(basename, dir).to_sym end end raise Zeitwerk::Error.new("I do not manage #{abspath}") unless root_namespace namespace = root_namespace cnames.reverse_each do |cname| namespace = namespace.const_get(cname, false) end raise Zeitwerk::Error.new("#{abspath} is shadowed") if shadowed_file?(abspath) namespace.const_get(base_cname, false) end |