What is the difference between require_relative and require in Ruby?
What is the difference between require_relative
and require
in Ruby?
Solution 1:
Just look at the docs:
require_relative
complements the builtin methodrequire
by allowing you to load a file that is relative to the file containing therequire_relative
statement.For example, if you have unit test classes in the "test" directory, and data for them under the test "test/data" directory, then you might use a line like this in a test case:
require_relative "data/customer_data_1"
Solution 2:
require_relative
is a convenient subset of require
require_relative('path')
equals:
require(File.expand_path('path', File.dirname(__FILE__)))
if __FILE__
is defined, or it raises LoadError
otherwise.
This implies that:
-
require_relative 'a'
andrequire_relative './a'
require relative to the current file (__FILE__
).This is what you want to use when requiring inside your library, since you don't want the result to depend on the current directory of the caller.
-
eval('require_relative("a.rb")')
raisesLoadError
because__FILE__
is not defined insideeval
.This is why you can't use
require_relative
in RSpec tests, which geteval
ed.
The following operations are only possible with require
:
require './a.rb'
requires relative to the current directory-
require 'a.rb'
uses the search path ($LOAD_PATH
) to require. It does not find files relative to current directory or path.This is not possible with
require_relative
because the docs say that path search only happens when "the filename does not resolve to an absolute path" (i.e. starts with/
or./
or../
), which is always the case forFile.expand_path
.
The following operation is possible with both, but you will want to use require
as it is shorter and more efficient:
-
require '/a.rb'
andrequire_relative '/a.rb'
both require the absolute path.
Reading the source
When the docs are not clear, I recommend that you take a look at the sources (toggle source in the docs). In some cases, it helps to understand what is going on.
require:
VALUE rb_f_require(VALUE obj, VALUE fname) {
return rb_require_safe(fname, rb_safe_level());
}
require_relative:
VALUE rb_f_require_relative(VALUE obj, VALUE fname) {
VALUE base = rb_current_realfilepath();
if (NIL_P(base)) {
rb_loaderror("cannot infer basepath");
}
base = rb_file_dirname(base);
return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}
This allows us to conclude that
require_relative('path')
is the same as:
require(File.expand_path('path', File.dirname(__FILE__)))
because:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
Solution 3:
From Ruby API:
require_relative complements the builtin method require by allowing you to load a file that is relative to the file containing the require_relative statement.
When you use require to load a file, you are usually accessing functionality that has been properly installed, and made accessible, in your system. require does not offer a good solution for loading files within the project’s code. This may be useful during a development phase, for accessing test data, or even for accessing files that are "locked" away inside a project, not intended for outside use.
For example, if you have unit test classes in the "test" directory, and data for them under the test "test/data" directory, then you might use a line like this in a test case:
require_relative "data/customer_data_1"
Since neither "test" nor "test/data" are likely to be in Ruby’s library path (and for good reason), a normal require won’t find them. require_relative is a good solution for this particular problem.
You may include or omit the extension (.rb or .so) of the file you are loading.
path must respond to to_str.
You can find the documentation at http://extensions.rubyforge.org/rdoc/classes/Kernel.html