require and require_relative
The require
method is used to load a file (or gems) on demand. For example:
The require method looks in the $LOAD_PATH
to find the file. The file path is expanded then we traverse the directories until there is a match.
NOTE: When we use rubygems in our code, there is an extra step that happens with the require method. In a rails appliction for example, have a look at the config/boot.rb
:
Rubygems aliases the Kernel#require
method, so we are calling the rubygems require method to find the required library/gem.
There is another method to load code called require_relative
. This can be used for code, that is in a relative location to the current file.
Ideally we should use require_relative
when the file is relative to the current file, it’s much faster than using require
. For accessing other libraries, continue to use the require
method.
Now that we understand what is happening with require, there are a couple more interesting concepts related to code loading which you may have come across in your rails application.
bootsnap
Bootsnap, authored by the folks at shopify, loads up your application, really fast.
Bootsnap optimizes all the places where you use require in your application and improves the lookup speed by caching the full path for a faster lookup. Bootsnap also does compilation caching, however the focus for this topic is require.
Bootsnap does some path pre-scanning, on app initialization or when modifying the $LOAD_PATH (e.g. adding a new folder to $LOAD_PATH). Absolute locations of all requireable files on the $LOAD_PATH are cached, then require uses that cached copy of requirables. This means we avoid having to check all $LOAD_PATHs for every single require.
Bootsnap is included by default in every rails application, keep in mind for optimal performance bootsnap should be loaded as early as possible. This does not mean that bootsnap should be added to the top of the Gemfile rather, in the application boot process, bootsnap should be right at the top. Here is an example of a rails application, that includes bootsnap right after rubygems.
This file is the first thing called in a rails application, inside the application.rb
.
Wherever you can, use bootsnap! For applications that have a big $LOAD_PATH
that could massively improve your app boot time.
Zeitwerk
Zeitwerk is an efficient and thread safe code loader for ruby. Your projects classes/modules are loaded on demand (autoloading) or upfront (eager loading). It has been included in rails 6.0 by default.
So what does this mean?
In our rails applications let’s say we have a user.rb
model. We want to use that inside the search_controller.rb
, a mailer or the console. The user model is autoloaded so we don’t have to add the require 'user'
in every class, we use the user model.
That’s the rails magic handled by zeitwerk.
For the keen observer, zeitwerk gem was not used proir to rails 6.0 and yet this behaviour still worked. Zeitwerk is a faster alternative to the classic autoloader, which will soon be deprecated.
Open up a rails console
We can directly call the user model without a require statement.