Лучший способ потребовать все файлы из каталога в ruby?
каков наилучший способ потребовать все файлы из каталога в ruby ?
11 ответов:
если это каталог относительно файла, который выполняет требование (например, вы хотите загрузить все файлы в каталог lib):
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }
Edit: на основе комментариев ниже, обновленная версия:
Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file| require File.basename(file, File.extname(file)) end
Если вы не удаляете расширение, то вам может потребоваться один и тот же файл дважды (ruby не поймет, что "foo" и "foo.rb " - это тот же файл). Требование одного и того же файла дважды может привести к ложным предупреждениям (например, "предупреждение: уже инициализированная константа").
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))
или в качестве альтернативы, если вы хотите, чтобы область файлов для загрузки в определенные папки:
Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require))
пояснение:
реж.Глоб принимает блок в качестве аргумента.
метод (: require)вернет метод require.
&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
не знает, что файл уже был необходим.здесь вместо этого мы добавляем каталог в путь загрузки, а затем требуем базового имени каждого *.файл в РБ.
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__
.
Dir[File.join(__dir__, "/app/**/*.rb")].each do |file| require file end
это будет работать рекурсивно на вашем локальном компьютере и удаленном (например, Heroku), который не использует относительные пути.
в Rails, вы можете сделать:
Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
обновление: исправлено с предложением @Jiggneshh Gohel удалить косые черты.