У чому різниця між require_relativeі requireв Ruby?
У чому різниця між require_relativeі requireв Ruby?
Відповіді:
Подивіться на документи :
require_relativeдоповнює вбудований методrequire, дозволяючи завантажити файл, який відносно файлу, що міститьrequire_relativeоператор.Наприклад, якщо у каталозі "тест" є одиничні тестові класи та дані для них у тестовому каталозі "тест / дані", ви можете використовувати такий рядок у тестовому випадку:
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());
}
Requ_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__
Від API Ruby :
Requ_relative доповнює вбудований метод вимагає, дозволяючи завантажувати файл, який відносно файлу, що містить оператор requ_relative.
Під час використання потрібного для завантаження файлу, ви зазвичай отримуєте доступ до функцій, які були правильно встановлені та зроблені доступними у вашій системі. вимагає не пропонує хорошого рішення для завантаження файлів у коді проекту. Це може бути корисно на етапі розробки, для доступу до тестових даних або навіть для доступу до файлів, які "заблоковані" всередині проекту, не призначеного для зовнішнього використання.
Наприклад, якщо у каталозі "тест" є одиничні тестові класи та дані для них у тестовому каталозі "тест / дані", ви можете використовувати такий рядок у тестовому випадку:
require_relative "data/customer_data_1"Оскільки "тест" і "тест / дані", ймовірно, не знаходяться на шляху бібліотеки Рубі (і з поважних причин), звичайна вимога їх не знайде. Requ_relative є хорошим рішенням для цієї конкретної проблеми.
Ви можете включити або пропустити розширення (.rb або .so) файлу, який ви завантажуєте.
шлях повинен відповідати to_str.
Ви можете знайти документацію на веб-сайті http://extensions.rubyforge.org/rdoc/classes/Kernel.html
requireдля встановлених дорогоцінних каменівrequire_relativeдля локальних файлівrequireвикористовує ваш, $LOAD_PATHщоб знайти файли.
require_relativeвикористовує поточне розташування файлу за допомогою оператора
Вимоги покладаються на те, що ви встановили (наприклад gem install [package]) пакет десь у вашій системі для цієї функції.
При використанні requireви можете використовувати " ./" формат для файлу в поточному каталозі, наприклад, require "./my_file"але це не є звичайною або рекомендованою практикою, і вам слід скористатися require_relativeнатомість.
Це просто означає, що включіть файл "відносно місця розташування файлу із заявою Requ_relative". Я зазвичай рекомендую, щоб файли знаходилися "в" поточному дереві каталогів на відміну від "вгору", наприклад , не використовувати
require_relative '../../../filename'
(до 3-х рівнів каталогів) у файловій системі, оскільки це, як правило, створює непотрібні та крихкі залежності. Однак у деяких випадках, якщо ви вже «заглиблені» в дерево каталогів, тоді може знадобитися «вгору і вниз» інша гілка дерева каталогів. Більш просто, можливо, не використовуйте Requ_relative для файлів поза цим сховищем (якщо припустимо, що ви використовуєте git, що в основному є фактичним стандартом на даний момент, кінець 2018 року).
Зауважте, що require_relativeвикористовується поточний каталог файлу із заявою Requ_relative (тому не обов'язково ваш поточний каталог, з якого ви використовуєте команду). Це зберігає require_relativeшлях "стабільним", оскільки він завжди має відношення до файлу, який вимагає його однаково.
Верхні відповіді правильні, але глибоко технічні. Для тих, хто новіший до Рубі:
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) постійний і requireO (N) лінійний. Тому, ймовірно, різниця полягає в тому, що require_relativeє кращим require.
require_relativeбуло швидше, тому що завантажувач не повинен проходити шлях завантаження в пошуках файлу. По суті, require_relativeзабезпечує пряме посилання.
Хочу додати, що при використанні Windows ви можете використовувати, require './1.rb'якщо скрипт виконується локально або з картографічного мережевого накопичувача, але при запуску зі \\servername\sharename\folderшляху UNC, який потрібно використовувати require_relative './1.rb'.
Я не втручаюся в дискусію, яку використовувати з інших причин.
require_relativeфайл Чи не могли б ви кинути ідею в цьому stackoverflow.com/questions/43487784 / ...
$:. Див stackoverflow.com/questions/2900370