What is the difference between require_relative
and require
in Ruby?
I want to add that when using Windows you can use require './1.rb'
if the script is run local or from a mapped network drive but when run from an UNC \\servername\sharename\folder
path you need to use require_relative './1.rb'
.
I don't mingle in the discussion which to use for other reasons.
The top answers are correct, but deeply technical. For those newer to Ruby:
require_relative
will most likely be used to bring in code from another file that you wrote. for example, what if you have data in ~/my-project/data.rb
and you want to include that in ~/my-project/solution.rb
? in solution.rb
you would add require_relative 'data'
.
it is important to note these files do not need to be in the same directory. require_relative '../../folder1/folder2/data'
is also valid.
require
will most likely be used to bring in code from a library someone else wrote.for example, what if you want to use one of the helper functions provided in the active_support
library? you'll need to install the gem with gem install activesupport
and then in the file require 'active_support'
.
require 'active_support/all'
"FooBar".underscore
Said differently--
require_relative
requires a file specifically pointed to relative to the file that calls it.
require
requires a file included in the $LOAD_PATH
.
require
for installed gemsrequire_relative
for local filesrequire
uses your $LOAD_PATH
to find the files.
require_relative
uses the current location of the file using the statement
Require relies on you having installed (e.g. gem install [package]
) a package somewhere on your system for that functionality.
When using require
you can use the "./
" format for a file in the current directory, e.g. require "./my_file"
but that is not a common or recommended practice and you should use require_relative
instead.
This simply means include the file 'relative to the location of the file with the require_relative statement'. I generally recommend that files should be "within" the current directory tree as opposed to "up", e.g. don't use
require_relative '../../../filename'
(up 3 directory levels) within the file system because that tends to create unnecessary and brittle dependencies. However in some cases if you are already 'deep' within a directory tree then "up and down" another directory tree branch may be necessary. More simply perhaps, don't use require_relative for files outside of this repository (assuming you are using git which is largely a de-facto standard at this point, late 2018).
Note that require_relative
uses the current directory of the file with the require_relative statement (so not necessarily your current directory that you are using the command from). This keeps the require_relative
path "stable" as it always be relative to the file requiring it in the same way.
I just saw the RSpec's code has some comment on require_relative
being O(1) constant and require
being O(N) linear. So probably the difference is that require_relative
is the preferred one than require
.
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"
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'
and require_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")')
raises LoadError
because __FILE__
is not defined inside eval
.
This is why you can't use require_relative
in RSpec tests, which get eval
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 for File.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'
and require_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__