В чем разница между require relative и require в Ruby?

в чем разница между require_relative и require в Ruby?

7 ответов


просто посмотри docs:

require_relative дополняет встроенный метод require, позволяя загружать файл, который относительно файла, содержащего require_relative заявление.

например, если у вас есть классы модульного теста в каталоге " test "и данные для них в каталоге" test/data", то вы можете использовать такую строку в тестовом случае:

require_relative "data/customer_data_1"

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, которые получают evaled.

следующие операции возможны только с 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_relative заявление.

при использовании require для загрузки файла, вы обычно доступ функциональность, которая была правильно установлен и доступен, в ваша система. требует не предлагать хорошее решение для загрузки файлов внутри проект код. Это может быть полезно на этапе разработки, для доступ к тестовым данным, или даже для доступ к файлам, которые "заблокированы" внутри проекта, не предназначенного для внешнее использование.

например, если у вас есть модульный тест классы в каталоге "test" и данные для их испытаний каталог" test/data", тогда вы можете используйте такую строку в тестовом примере:

require_relative "data/customer_data_1" 

Так как ни "тест "или" тест/данные", вероятно, в библиотеке Руби путь (и для хорошая причина), нормальный требует не будет найти их. require_relative хороший решение этой конкретной проблемы.

вы можете включить или отключить расширение (.RB или .так) файла погрузка.

путь должен отвечать to_str.

вы можете найти документацию на http://extensions.rubyforge.org/rdoc/classes/Kernel.html


резюме

использовать require для установки драгоценных камней

использовать require_relative для локальных файлов

require использует $LOAD_PATH найти файлы.
Это как требует таких как

require 'date'

работа-они полагаются на вас, установив (например,gem install [package]) пакет где-то в системе для этой функциональности.

при использовании require вы можете используйте "./" формат файла в текущий каталог, например,require "./my_file" но это не общепринятая и рекомендуемая практика, и вы должны использовать require_relative вместо.

при использовании require_relative, Я рекомендую, чтобы файлы были "внутри" текущего дерева каталогов, а не "вверх", например не использовать

require_relative '../../../filename'

(до 3 уровней каталогов) в файловой системе, потому что это имеет тенденцию создавать ненужные и хрупкие зависимости.

отметим, что require_relative использует текущий каталог файла с require_relative заявление (так что не обязательно ваш текущий каталог).


лучшие ответы правильные, но глубоко технические. Для тех, кто новее Рубина ... --14-->

  • require_relative, скорее всего, будет использоваться для ввода кода из другого файла, который вы написали.

например, что если у вас есть данные в ~/my-project/data.rb и вы хотите включить, что в ~/my-project/solution.rb? в solution.rb добавить require_relative 'data'.

важно отметить, что эти файлы не должны находиться в одном каталоге. require_relative '../../folder1/folder2/data' тоже действительный.

  • require скорее всего, будет использоваться для ввода кода из библиотеки, которую написал кто-то другой.

например, что делать, если вы хотите использовать одну из вспомогательных функций, предусмотренных в active_support библиотеки? вам нужно будет установить gem с 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.


хочу добавить, что при использовании Windows, вы можете использовать require './1.rb' Если скрипт выполняется локально или с подключенного сетевого диска, но при запуске из UNC \servername\sharename\folder path вам нужно использовать require_relative './1.rb' Я не вмешиваюсь в дискуссию, которую использовать по другим причинам.