The autoload Method in Ruby
In this article we’re going to explore the following topics:
autoload
registration & lazy loading- the
Module#autoload?
method - the
Module#autoload
method behind the scene
If you want to Gain In-depth Knowledge on Ruby On Rails, please go through this link Ruby On Rails Online Training
autoload
registration & lazy loading
The Module#autoload
method registers a file path to be loaded the first time that a specified module or class is accessed in the namespace of the calling module or class.
Let’s detail a simple example to break down the previous assertion.
module Car autoload(:Engine, './engine.rb') puts "The Engine module isn't yet loaded!" Engine puts "The Engine module has been successfully loaded!" end
module Engine puts 'The Engine module is loading!' end
now let’s run our Ruby script
gt; ruby car.rbThe 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 autoload(:Engine, ‘./engine.rb’)
The engine.rb
is not yet loaded.
In effect, this file is only loaded when we explicitly call the Engine
module.
This mechanism allows Ruby to only load the files that contain the modules/classes used by the execution flow of the running program.
The Module#autoload?
method
The Module#autoload?
is in charge of checking if a registered module/class in a specific namespace has already been loaded or not.
It’s also used for checking if a module is registered (or not) as autoload in a specific namespace
module A autoload(:B, './b.rb') p autoload?(:B) B p autoload?(:B) end
module B puts 'The module B is loading!' end
produces
"./b.rb"The module B is loading!nil
The first call to autoload? :B
returns the "./b.rb"
file path.
Then the B
module is loaded via a loading of the b.rb
file.
Finally, the second call to autoload? :B
returns nil
because the B
module is already loaded.
So, let’s autoload
a C
module outside of the the A
namespace
autoload(:C, './c.rb') module A p autoload? :C end p autoload? :C
module C end
produces
nil"./c.rb"
The call to autoload? :C
within the A
namespace returns nil
because the :C
module is registered as autoload
in the top-level namespace and not in the A
namespace.
Take your career to new heights of success with an Ruby On Rails Training
In contrary, the second call to autoload? :C
is invoked within the top-level namespace. As it’s within the same namespace as the autoload(:C, './c.rb')
registration then it returns the "./c.rb"
file path.
Now that we are more familiar with the autoload
registration mechanism, let’s dive into what happens behind the scene when we register and call a module.
The Module#autoload
method behind the scene
When the Module#autoload
method is called within a specific namespace then the module/class and the file path given as arguments of the method are stored in an internal hash table.
Let’s have a look to this example
module A autoload(:B, './b.rb') p constants end
module B end
produces
[:B]
Here, we can see that the B
constant exists even if it hasn’t been loaded yet.
In effect, a call to autoload
will automatically create a constant named as the first argument of the method and flagged as autoload
registered. The value of this constant will be undefined and NOT nil
.
When the B
module will be invoked then Ruby will search for the B
entry within the constants hash table of the A
namespace.
It’ll then load the file using the Kernel#require
method
Finally the constant hash table will unflag as autoload
the B
module.