В чем разница между require_relative
и require
в Ruby?
В чем разница между require_relative
и require
в Ruby?
Ответы:
Просто посмотрите на документы :
require_relative
дополняет встроенный методrequire
, позволяя загружать файл относительно файла, содержащегоrequire_relative
инструкцию.Например, если у вас есть классы модульных тестов в каталоге «test», а данные для них - в каталоге «test / data», то вы можете использовать такую строку в тестовом примере:
require_relative "data/customer_data_1"
require './file.rb'
и require_relative 'file.rb'
?
require_relative
позволяет вам «загрузить файл, относящийся к файлу, содержащему require_relative
инструкцию ». С require
, ./
указывает путь относительно вашего текущего рабочего каталога.
require str
всегда будет искать по каталогам в $ LOAD_PATH. Вы должны использовать, require_relative
когда файл, который вам нужно загрузить, существует где-то относительно файла, который вызывает загрузку. Резерв require
для «внешних» зависимостей.
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
ред.
Следующие операции возможны только с 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__
Из Ruby API :
require_relative дополняет встроенный метод require, позволяя загрузить файл, относящийся к файлу, содержащему оператор require_relative.
Когда вы используете требование загрузки файла, вы обычно получаете доступ к функциональности, которая была правильно установлена и сделана доступной в вашей системе. require не предлагает хорошего решения для загрузки файлов в коде проекта. Это может быть полезно на этапе разработки, для доступа к тестовым данным или даже для доступа к файлам, которые «заблокированы» внутри проекта и не предназначены для внешнего использования.
Например, если у вас есть классы модульных тестов в каталоге «test», а данные для них - в каталоге «test / data», то вы можете использовать такую строку в тестовом примере:
require_relative "data/customer_data_1"
Поскольку ни «test», ни «test / data», скорее всего, не находятся в пути к библиотеке Ruby (и по уважительной причине), обычное требование не найдет их. require_relative - хорошее решение для этой конкретной проблемы.
Вы можете включить или опустить расширение (.rb или .so) загружаемого вами файла.
путь должен отвечать to_str.
Вы можете найти документацию по адресу http://extensions.rubyforge.org/rdoc/classes/Kernel.html.
require
для установленных драгоценных камнейrequire_relative
для локальных файловrequire
использует ваш, $LOAD_PATH
чтобы найти файлы.
require_relative
использует текущее местоположение файла, используя инструкцию
Require зависит от того, что вы установили (например gem install [package]
) пакет где-то в вашей системе для этой функции.
При использовании require
вы можете использовать ./
формат " " для файла в текущем каталоге, например, require "./my_file"
но это не является обычной или рекомендуемой практикой, и вы должны использовать require_relative
вместо этого.
Это просто означает включение файла «относительно местоположения файла с оператором require_relative». Обычно я рекомендую, чтобы файлы находились «внутри» текущего дерева каталогов, а не «вверх», например , не используйте
require_relative '../../../filename'
(до 3 уровней каталогов) в файловой системе, потому что это имеет тенденцию создавать ненужные и хрупкие зависимости. Однако в некоторых случаях, если вы уже «глубоко» в дереве каталогов, тогда может понадобиться «вверх и вниз» другой ветви дерева каталогов. Проще говоря, не используйте require_relative для файлов за пределами этого репозитория (при условии, что вы используете git, который на данный момент является стандартом де-факто, конец 2018 года).
Обратите внимание, что require_relative
используется текущий каталог файла с оператором require_relative (поэтому не обязательно ваш текущий каталог, из которого вы используете команду). Это сохраняет require_relative
путь «стабильным», так как он всегда будет относиться к файлу, требующему его одинаковым образом.
Лучшие ответы правильные, но глубоко технические. Для новичков в 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
.
Я только что видел, что в коде RSpec есть некоторые комментарии о том, require_relative
что O (1) константа и require
O (N) линейно. Так что, вероятно, разница в том, что require_relative
предпочтительнее, чем require
.
require_relative
было быстрее, потому что загрузчик не должен пересекать путь загрузки при поиске файла. По сути, require_relative
обеспечивает прямую ссылку.
Я хочу добавить, что при использовании Windows вы можете использовать, require './1.rb'
если скрипт запускается локально или с подключенного сетевого диска, но при запуске с UNC- \\servername\sharename\folder
пути вам нужно использоватьrequire_relative './1.rb'
.
Я не смешиваюсь в обсуждении, которое можно использовать по другим причинам.
$:
. См stackoverflow.com/questions/2900370