Module: Im::Registry
- Defined in:
- lib/im/registry.rb
Overview
:nodoc: all
Class Attribute Summary collapse
- .autoloaded_modules ⇒ Object readonly
-
.autoloads ⇒ Object
readonly
Maps absolute paths to the loaders responsible for them.
-
.gem_loaders_by_root_file ⇒ Object
readonly
Registers gem loaders to let
for_gembe idempotent in case of reload. -
.inceptions ⇒ Object
readonly
This hash table addresses an edge case in which an autoload is ignored.
-
.loaders ⇒ Object
readonly
Keeps track of all loaders.
- .paths ⇒ Object readonly
Class Method Summary collapse
- .inception?(cpath) ⇒ Boolean
- .loader_for(path) ⇒ Object
-
.loader_for_gem(root_file, warn_on_extra_files:) ⇒ Object
This method returns always a loader, the same instance for the same root file.
- .on_unload(loader) ⇒ Object
- .register_autoload(loader, abspath) ⇒ Object
- .register_autoloaded_module(mod, module_name, loader) ⇒ Object
- .register_inception(cpath, abspath, loader) ⇒ Object
-
.register_loader(loader) ⇒ Object
Registers a loader.
- .register_path(loader, abspath) ⇒ Object
- .unregister_autoload(abspath) ⇒ Object
- .unregister_loader(loader) ⇒ Object
- .unregister_path(abspath) ⇒ Object
Class Attribute Details
.autoloaded_modules ⇒ Object (readonly)
73 74 75 |
# File 'lib/im/registry.rb', line 73 def autoloaded_modules @autoloaded_modules end |
.autoloads ⇒ Object (readonly)
Maps absolute paths to the loaders responsible for them.
This information is used by our decorated ‘Kernel#require` to be able to invoke callbacks and autovivify modules.
26 27 28 |
# File 'lib/im/registry.rb', line 26 def autoloads @autoloads end |
.gem_loaders_by_root_file ⇒ Object (readonly)
Registers gem loaders to let for_gem be idempotent in case of reload.
17 18 19 |
# File 'lib/im/registry.rb', line 17 def gem_loaders_by_root_file @gem_loaders_by_root_file end |
.inceptions ⇒ Object (readonly)
This hash table addresses an edge case in which an autoload is ignored.
For example, let’s suppose we want to autoload in a gem like this:
# lib/my_gem.rb
loader = Im::Loader.new
loader.push_dir(__dir__)
loader.setup
module loader::MyGem
end
if you require “my_gem”, as Bundler would do, this happens while setting up autoloads:
1. Object.autoload?(:MyGem) returns `nil` because the autoload for
the constant is issued by Im while the same file is being
required.
2. The constant `MyGem` is undefined while setup runs.
Therefore, a directory lib/my_gem would autovivify a module according to the existing information. But that would be wrong.
To overcome this fundamental limitation, we keep track of the constant paths that are in this situation —in the example above, “MyGem”— and take this collection into account for the autovivification logic.
Note that you cannot generally address this by moving the setup code below the constant definition, because we want libraries to be able to use managed constants in the module body:
module loader::MyGem
include MyConcern
end
69 70 71 |
# File 'lib/im/registry.rb', line 69 def inceptions @inceptions end |
.loaders ⇒ Object (readonly)
Keeps track of all loaders. Useful to broadcast messages and to prevent them from being garbage collected.
11 12 13 |
# File 'lib/im/registry.rb', line 11 def loaders @loaders end |
.paths ⇒ Object (readonly)
30 31 32 |
# File 'lib/im/registry.rb', line 30 def paths @paths end |
Class Method Details
.inception?(cpath) ⇒ Boolean
135 136 137 138 139 |
# File 'lib/im/registry.rb', line 135 def inception?(cpath) if pair = inceptions[cpath] pair.first end end |
.loader_for(path) ⇒ Object
147 148 149 |
# File 'lib/im/registry.rb', line 147 def loader_for(path) paths[path] end |
.loader_for_gem(root_file, warn_on_extra_files:) ⇒ Object
This method returns always a loader, the same instance for the same root file. That is how Im::Loader.for_gem is idempotent.
99 100 101 |
# File 'lib/im/registry.rb', line 99 def loader_for_gem(root_file, warn_on_extra_files:) gem_loaders_by_root_file[root_file] ||= GemLoader._new(root_file, warn_on_extra_files: warn_on_extra_files) end |
.on_unload(loader) ⇒ Object
153 154 155 156 |
# File 'lib/im/registry.rb', line 153 def on_unload(loader) autoloads.delete_if { |_path, object| object == loader } inceptions.delete_if { |_cpath, (_path, object)| object == loader } end |
.register_autoload(loader, abspath) ⇒ Object
105 106 107 |
# File 'lib/im/registry.rb', line 105 def register_autoload(loader, abspath) paths[abspath] = autoloads[abspath] = loader end |
.register_autoloaded_module(mod, module_name, loader) ⇒ Object
141 142 143 |
# File 'lib/im/registry.rb', line 141 def register_autoloaded_module(mod, module_name, loader) autoloaded_modules[mod.object_id] = [module_name, loader, []] end |
.register_inception(cpath, abspath, loader) ⇒ Object
129 130 131 |
# File 'lib/im/registry.rb', line 129 def register_inception(cpath, abspath, loader) inceptions[cpath] = [abspath, loader] end |
.register_loader(loader) ⇒ Object
Registers a loader.
79 80 81 |
# File 'lib/im/registry.rb', line 79 def register_loader(loader) loaders << loader end |
.register_path(loader, abspath) ⇒ Object
117 118 119 |
# File 'lib/im/registry.rb', line 117 def register_path(loader, abspath) paths[abspath] = loader end |
.unregister_autoload(abspath) ⇒ Object
111 112 113 |
# File 'lib/im/registry.rb', line 111 def unregister_autoload(abspath) autoloads.delete(abspath) end |
.unregister_loader(loader) ⇒ Object
85 86 87 88 89 90 91 92 |
# File 'lib/im/registry.rb', line 85 def unregister_loader(loader) loaders.delete(loader) gem_loaders_by_root_file.delete_if { |_, l| l == loader } autoloads.delete_if { |_, l| l == loader } paths.delete_if { |_, l| l == loader } inceptions.delete_if { |_, (_, l)| l == loader } autoloaded_modules.delete_if { |_, (_, l, _)| l == loader } end |
.unregister_path(abspath) ⇒ Object
123 124 125 |
# File 'lib/im/registry.rb', line 123 def unregister_path(abspath) paths.delete(abspath) end |