In this article, we will explore the following topics:
- autoload registration & lazy loading
- Method module # autoload? method
- Behind the Module # autoload method
I. autoload registration & lazy loading
Module # autoload method to register a file path is loaded for the first time when the namespace of a module or a specific class called.
For example:
1 2 3 4 5 6 7 8 | module Car autoload(:Engine, './engine.rb') puts "The Engine module isn't yet loaded!" Engine puts "The Engine module has been successfully loaded!" end |
1 2 3 4 | module Engine puts 'The Engine module is loading!' end |
Now run the Ruby script:
1 2 3 4 5 | $> ruby car.rb The Engine module isn’t yet loaded! The Engine module is loading! The Engine module has been successfully loaded! |
Here we see that after a call to automatically load autoload (: Engine, ‘./engine.rb’) , engine.rb has not been loaded yet.
In fact, this file is only loaded when we explicitly call the Engine module.
This mechanism allows Ruby to not be used indiscriminately, but only to load files containing modules / classes used by the executable of the running program.
II. Method # autoload method?
Module # autoload? It is responsible for checking whether the module / class registered in a namespace is loaded .
It is also used to check if a module is registered (or not) in a namespace.
1 2 3 4 5 6 7 8 | module A autoload(:B, './b.rb') p autoload?(:B) B p autoload?(:B) end |
1 2 3 4 | module B puts 'The module B is loading!' end |
Run the result as follows:
1 2 3 4 | "./b.rb" The module B is loading! nil |
First autoload call ? : B returns the path “./b.rb” .
Module B is then loaded through the loading of the b.rb file.
Finally, the second autoload? (: B) call returns nil because module B is already loaded.
So autoload try a C module outside of namespace A
1 2 3 4 5 6 7 8 | autoload(:C, './c.rb') module A p autoload? :C end p autoload? :C |
1 2 3 | module C end |
Run the result as follows:
1 2 3 | nil "./c.rb" |
Call to autoload? : C in namespace A returns nil because module : C is registered autoload in the top-level namespace, not in namespace A.
Conversely, the second call to autoload? : C is called in the top-level namespace. It is located in the same autoload registered namespace (: C, ‘./c.rb’) so it returns the path *** “./ c .rb” ***.
Now that we are more familiar with the autoload registration mechanism, let’s explore what happens behind us when we register and call a module.
III. Behind the Module # autoload method
When the Module # autoload method is called in a namespace, the module / class and file path that are given as arguments of the method are stored in the internal hash table.
Let’s follow this example:
1 2 3 4 5 6 | module A autoload(:B, './b.rb') p constants end |
1 2 3 | module B end |
Run the result as follows:
1 2 | [:B] |
Here, we can see that the constant B exists even if it has not been loaded yet.
In fact, a call to autoload automatically creates a constant named the first argument of the method and is flagged as the registered autoload . The value of this constant will not be determined and will NOT carry an empty value.
When module B is called, Ruby will look for the entry B in the hash constant table of namespace A.
Then it will load the file using the Kernel # require method
Finally, the hash constant table will disconnect when autoload of module B.
The article is translated from: https://medium.com/rubycademy/the-autoload-method-in-ruby-11fd079562ef