В чем разница между require_relative
и require
в Ruby?
В чем разница между require_relative и require в Ruby?
Ответ 1
Просто посмотрите docs:
require_relative
дополняет встроенный методrequire
, позволяя загружать файл, относящийся к файлу, содержащему операторrequire_relative
.Например, если в каталоге "test" есть unit test классы и данные для них в тестовом каталоге "test/data", вы можете использовать такую строку в тестовом примере:
require_relative "data/customer_data_1"
Ответ 2
require_relative
является удобным подмножеством require
require_relative('path')
равна:
require(File.expand_path('path', File.dirname(__FILE__)))
если __FILE__
определено или в противном случае возникает LoadError
.
Это означает, что:
-
require_relative 'a'
иrequire_relative './a'
требуют относительно текущего файла (__FILE__
).Это то, что вы хотите использовать, когда вы требуете в своей библиотеке, поскольку вы не хотите, чтобы результат зависел от текущего каталога вызывающего.
-
eval('require_relative("a.rb")')
вызываетLoadError
, потому что__FILE__
не определяется внутриeval
.Вот почему вы не можете использовать
require_relative
в тестах RSpec, которые получаютeval
ed.
Следующие операции возможны только при require
:
-
require './a.rb'
требуется относительно текущего каталога -
require 'a.rb'
используется путь поиска ($LOAD_PATH
). Он не находит файлы относительно текущей директории или пути.Это невозможно в
require_relative
, потому что документы говорят, что поиск по пути происходит только тогда, когда "имя файла не разрешено к абсолютному пути" (т.е. начинается с/
или./
или../
), что всегда имеет место дляFile.expand_path
.
В обоих случаях возможна следующая операция, но вы захотите использовать require
, поскольку она короче и эффективнее:
-
require '/a.rb'
иrequire_relative '/a.rb'
оба требуют абсолютного пути.
Чтение источника
Когда документы не ясны, я рекомендую вам взглянуть на источники (переключить источник в документы). В некоторых случаях это помогает понять, что происходит.
требуется:
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());
}
Это позволяет сделать вывод, что
require_relative('path')
совпадает с:
require(File.expand_path('path', File.dirname(__FILE__)))
потому что:
rb_file_absolute_path =~ File.expand_path
rb_file_dirname1 =~ File.dirname
rb_current_realfilepath =~ __FILE__
Ответ 3
В Ruby API:
require_relative дополняет встроенный метод, позволяющий вам для загрузки файла, относящегося к файл, содержащий require_relative утверждение.
При использовании требуется загрузить файл, вы обычно получаете доступ функциональность, которая была должным образом установленных и доступных в вашей системы. требуют не предлагать хорошее решение для загрузки файлов внутри код проекта. Это может быть полезно на этапе разработки для доступа к тестовым данным или даже для доступ к файлам, которые "заблокированы" внутри проекта, не предназначенного для наружное использование.
Например, если у вас есть unit testклассов в каталоге "test" и данные для них под тестом "test/data", тогда вы можете используйте такую строку в тестовом примере:
require_relative "data/customer_data_1"
Поскольку ни "тест" или "тест/данные", скорее всего, быть в пути библиотеки Rubys (и для хорошая причина), нормальный требует Найди их. require_relative - хороший решение этой конкретной проблемы.
Вы можете включить или опустить расширение (.rb или .so) файла, который вы загрузки.
путь должен соответствовать to_str.
Документацию можно найти в http://extensions.rubyforge.org/rdoc/classes/Kernel.html
Ответ 4
require
использует текущий каталог, из которого вы запускаете программу из
require_relative
использует каталог, в котором находится сама программа.
Например, если программа находится в ~/code
и называется 1.rb
, и вы сделали cd в этом каталоге
cd ~/code
и вы пытаетесь запустить рубиновую программу с помощью
ruby 1.rb
затем внутри 1.rb
require './2.rb'
require_relative '3.rb'
оба будут работать.
Однако, если вы находитесь в другом каталоге, скажите
cd ~/tmp
и вы пытаетесь запустить программу с помощью
ruby ../1.rb
тогда вы получите сообщение об ошибке, например
/home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- ./2.rb (LoadError)
from /home/durrantm/.rvm/rubies/ruby-2.1.2/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from ../1.rb:1:in `<main>'
при попытке использовать
require './2.rb'
тогда как
require_relative '3.rb'
все еще работает нормально _ потому что ссылка (до 3.rb
) относится к тому каталогу, в котором находится программа (1.rb
).
Ответ 5
Лучшие ответы правильные, но глубоко технические. Для тех, кто новичок в Ruby -
-
require_relative
, скорее всего, будет использоваться для ввода кода из другого файла, который вы написали.
например, что, если у вас есть данные в ~/my-project/data.rb
и вы хотите включить это в ~/my-project/solution.rb
? в solution.rb
вы добавили бы require_relative 'data'
.
Важно отметить, что эти файлы не обязательно должны находиться в одном каталоге. require_relative '../../folder1/folder2/data'
.
-
require
, скорее всего, будет использоваться для ввода кода из библиотеки, которую кто-то написал.
например, что, если вы хотите использовать одну из вспомогательных функций, предоставляемых в библиотеке active_support
? вам нужно установить драгоценный камень с помощью gem install activesupport
, а затем в файл require 'active_support'
.
require 'active_support/all'
"FooBar".underscore
Говорят иначе -
-
require_relative
требуется файл, специально указываемый относительно файла, который его вызывает. -
require
требуется файл, включенный в $LOAD_PATH.
Ответ 6
Я только что видел, что код RSpec имеет некоторый комментарий к require_relative
, являющийся константой O (1), а require
- O (N). Вероятно, разница в том, что require_relative
является предпочтительным, чем require
.
Ответ 7
Я хочу добавить, что при использовании окон вы можете использовать require './1.rb'
, если script запускается локально или с подключенного сетевого диска, но при запуске из пути UNC\servername\sharename\folder вам нужно использовать require_relative './1.rb'
Я не участвую в обсуждении, которое можно использовать по другим причинам.