У чому різниця між 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) постійний і require
O (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