What’s the relationship between require, $LOAD_PATH and $LOADED_FEATURES in Ruby?

Search for a command to run...

No comments yet. Be the first to comment.
PostgreSQL Upgrade and Database Restoration Guide To support the pgvector gem, I upgraded my local Postgres.app from v13 to v17 on macOS. Below is the full upgrade and restoration process for my project. Environment OS: macOS PostgreSQL: Upgraded f...

Introduction In Ruby on Rails applications, handling database transactions efficiently is crucial to maintaining data integrity. One common issue developers face is dealing with runtime errors caused by unpersisted changes when using the with_lock me...

Environment MacOS Sonoma 14.3 Original Ruby version: 2.7.8 Ruby Version Manager: RVM 1.29.12 Goal Upgrade Ruby from 2.7.8 to 3.0.6. Issues Description After successfully installing Ruby 3.0.6, I encountered difficulties running bundle install in...

In my daily job, I mainly use Rails framework. To make code readable and maintainable, we seldom write raw SQL in the codebase. Instead, we use Rails's ActiveRecord::QueryMethods module which helps developers write beautiful queries quickly. For exam...

It is common to see require 'something' in a Rails application. But what exactly does require do?
require used for in Ruby?require is used to load external libraries or modules into your program. For example,
Before you require the JSON module
# in irb
JSON
#=> Traceback (most recent call last):
4: from /Users/lynnbright/.rvm/rubies/ruby-2.7.8/bin/irb:23:in `<main>'
3: from /Users/lynnbright/.rvm/rubies/ruby-2.7.8/bin/irb:23:in `load'
2: from /Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
1: from (irb):3
NameError (uninitialized constant JSON)
After you require the JSON module
# in irb
require 'JSON'
#=> true
JSON
#=> JSON
data = '{"name": "John", "age": 30}'
#=> => "{\"name\": \"John\", \"age\": 30}"
JSON.parse(data)
#=> {"name"=>"John", "age"=>30}
require, $LOAD_PATH and $LOADED_FEATURES in Ruby?Before the file is loaded, there are some steps that Ruby will do.
First, when we use require, it means that we ask Ruby to load the file. However, it is needless to load the same file again and again, right? This is how the $LOAD_PATH and $LOADED_FEATURES play important roles.
$LOAD_PATH: It is a global variable used to locate the file.
$LOADED_FEATURES: It is a global variable, too. It’s used to keep tracking of which files have been loaded successfully using require.
When require is called, Ruby looks for a specific file from $LOAD_PATH which contains an array of directories.
If the file is found, Ruby loads and executes it.
If the file is not found listed in the $LOAD_PATH, LoadError is raised.
# in irb
require 'abc'
#=> Traceback (most recent call last):
6: from /Users/lynnbright/.rvm/rubies/ruby-2.7.8/bin/irb:23:in `<main>'
5: from /Users/lynnbright/.rvm/rubies/ruby-2.7.8/bin/irb:23:in `load'
4: from /Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
3: from (irb):9
2: from /Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:83:in `require'
1: from /Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:83:in `require'
LoadError (cannot load such file -- abc)
If the file is found, before actually loading it, Ruby uses $LOADED_FEATURES, which contains an array of files, to check if the file is already included in the array.
If it is included in the array, that means the file has been loaded. If not, it will be added to $LOADED_FEATURES to prevent it from loaded again.
# in irb
$LOAD_PATH
#=> ["/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/timeout-0.4.1/lib", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/site_ruby/2.7.0", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/site_ruby/2.7.0/x86_64-darwin21", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/site_ruby", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/vendor_ruby/2.7.0", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/vendor_ruby/2.7.0/x86_64-darwin21", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/vendor_ruby", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/2.7.0", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/2.7.0/x86_64-darwin21"]
$LOADED_FEATURES
#=> ["enumerator.so", "thread.rb", "rational.so", "complex.so",....]
$LOADED_FEATURES.length
#=> 171
require 'json'
#=> true
# You can see that the "json" directory has been included into the $LOAD_PATH.
$LOAD_PATH
#=> ["/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/timeout-0.4.1/lib", "/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/json-2.7.1/lib", "/Users/lynnbright/.rvm/gems/ruby-2.7.8/extensions/x86_64-darwin-21/2.7.0/json-2.7.1", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/site_ruby/2.7.0", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/site_ruby/2.7.0/x86_64-darwin21", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/site_ruby", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/vendor_ruby/2.7.0", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/vendor_ruby/2.7.0/x86_64-darwin21", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/vendor_ruby", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/2.7.0", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/2.7.0/x86_64-darwin21"]
# The array elements increased from 171 to 180, indicating that new elements have been added.
$LOADED_FEATURES.length
#=> 180
$LOADED_FEATURES
#=> [...., "/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/json-2.7.1/lib/json/version.rb", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/2.7.0/ostruct/version.rb", "/Users/lynnbright/.rvm/rubies/ruby-2.7.8/lib/ruby/2.7.0/ostruct.rb", "/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/json-2.7.1/lib/json/generic_object.rb", "/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/json-2.7.1/lib/json/common.rb", "/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/json-2.7.1/lib/json/ext/parser.bundle", "/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/json-2.7.1/lib/json/ext/generator.bundle", "/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/json-2.7.1/lib/json/ext.rb", "/Users/lynnbright/.rvm/gems/ruby-2.7.8/gems/json-2.7.1/lib/json.rb"]
# Attempting to require 'json' again returns false because it is already included in $LOADED_FEATURES.
require 'json'
#=> false
In summary:
require is used to load the specific file.
$LOAD_PATH is used to locate where the file is.
$LOADED_FEATURES is used to keep tracking of which files have been loaded successfully using require.