Який найкращий спосіб вимагати всіх файлів з каталогу в рубіні?
Який найкращий спосіб вимагати всіх файлів з каталогу в рубіні?
Відповіді:
Як щодо:
Dir["/path/to/directory/*.rb"].each {|file| require file }
require
не плутає наявність чи відсутність .rb
розширення. Тестували на МРТ 1.8.7-p374, 2.1.5 та 2.2.0 тестували. Ця міська легенда походить з Rails, де "розумне" автозавантаження демонструвало поведінку, яку він описує у старих версіях (і може все ще демонструвати її).
Якщо це каталог відносно файлу, який вимагає (наприклад, ви хочете завантажити всі файли в каталозі lib):
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }
Редагувати: На підставі коментарів нижче оновлена версія:
Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
__dir__
замість File.dirname(__FILE__)
.
require_relative
вимагаєте вимагати всіх файлів у каталозі?
Спробуйте Requemall дорогоцінний камінь:
Це дозволяє вам просто:
require_all 'path/to/directory'
require_all
циклічне рішення залежності залежить від проблеми у вихідному коді: у вас є вихідні файли Ruby, які не потребують їх залежностей. Це закриває двері при завантаженні скальпелем, зобов’язуючи вас завантажувати все або нічого. Це не є проблемою в невеликих бібліотеках, але це рішення, яке ви повинні приймати свідомо.
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file|
require File.basename(file, File.extname(file))
end
Якщо ви не знімете розширення, то, можливо, два рази вимагати один і той же файл (рубін не зрозуміє, що "foo" і "foo.rb" - це один і той же файл). Якщо два рази вимагати один і той самий файл, може призвести до помилкових попереджень (наприклад, "попередження: вже ініціалізована константа").
require "foo.rb"; require "foo";
завантажуватимуться foo.rb
лише один раз.
require
не бентежить наявність чи відсутність .rb
розширення. Тестували на МРТ 1.8.7-p374, 2.1.5 та 2.2.0. Ця міська легенда походить з Rails, де "розумне" автозавантаження демонструвало поведінку, описану в старих версіях (і може все ще проявляти її).
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))
або, якщо ви хочете обширити файли для завантаження в певні папки:
Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require))
пояснення:
Dir.glob в якості аргументу бере блок.
метод (: вимагає) поверне метод вимагати.
& method (: вимагати) перетворить метод у блок.
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )
виключає залежність від платформи (наприклад, '/' або '\'). Добре працює. Дякую.
Найкращий спосіб - додати каталог до шляху завантаження, а потім require
базову назву кожного файлу. Це тому, що ви хочете уникнути випадкового вимагання одного і того ж файлу двічі - часто це не призначена поведінка. Буде файл завантажений чи ні, залежить від того, чи require
бачив шлях, пройдений до нього раніше. Наприклад, цей простий сеанс irb показує, що ви можете помилково вимагати та завантажувати один і той же файл двічі.
$ irb
irb(main):001:0> require 'test'
=> true
irb(main):002:0> require './test'
=> true
irb(main):003:0> require './test.rb'
=> false
irb(main):004:0> require 'test'
=> false
Зауважте, що перші два рядки повертаються, true
тобто один і той же файл завантажувались обидва рази. Коли шляхи використовуються, навіть якщо шляхи вказують на те саме місце, require
не знає, що файл вже був потрібний.
Тут замість цього ми додаємо каталог до шляху завантаження, а потім вимагаємо базове ім'я кожного * .rb-файлу всередині.
dir = "/path/to/directory"
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }
Якщо ви не переймаєтесь тим, що потрібен файл не один раз, або ви маєте намір просто завантажити вміст файлу, можливо, його load
слід використовувати замість require
. Використовуйте навантаження в цьому випадку, оскільки воно краще виражає те, що ви намагаєтеся досягти. Наприклад:
Dir["/path/to/directory/*.rb"].each {|file| load file }
Замість поєднання шляхів, як у деяких відповідях, я використовую File.expand_path
:
Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file|
require file
end
Оновлення:
Замість використання File.dirname
ви можете зробити наступне:
Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
require file
end
Де ..
смужки імені файлу __FILE__
.
File.expand_path
Rails.root.join
відповіді також працюють, якщо ви знаходитесь в рейках.
У Rails ви можете:
Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
Оновлення: виправлено пропозицію @Jiggneshh Gohel для видалення косої риски.
Rails.root.join('/lib')
, не створює правильний шлях. Я виявив, що це працює правильно:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
А що: require_relative *Dir['relative path']
?
require_relative *Dir['*.rb']
працювати, якщо є лише один ruby-скрипт. Але якщо знайдено кілька рубінових скриптів, ви отримаєтеrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)