Лучший способ потребовать все файлы из каталога в 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))
пояснение:
реж.Глоб!--10--> принимает блок в качестве аргумента.
метод (: 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
. Используйте load в этом случае, потому что он лучше выражает то, что вы пытаетесь выполнить. Например:
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 }
Update: исправлено с предложением @Jiggneshh Gohel удалить косые черты.
Я на несколько лет опоздал на вечеринку, но мне нравится это однострочное решение, которое я использовал, чтобы rails включал все в app / workers/concerns:
Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }