Лучший способ потребовать все файлы из каталога в рубине?

Какой лучший способ потребовать все файлы из каталога в ruby?

Ответ 1

Как насчет:

Dir["/path/to/directory/*.rb"].each {|file| require file }

Ответ 2

Если это каталог, относящийся к файлу, который требует (например, вы хотите загрузить все файлы в каталоге lib):

Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }

Ответ 4

Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file| 
  require File.basename(file, File.extname(file))
end

Если вы не разделяете расширение, вы можете в конечном итоге потребовать один и тот же файл дважды (рубин не поймет, что "foo" и "foo.rb" являются одним и тем же файлом). Требование одного и того же файла дважды может привести к ложным предупреждениям (например, "предупреждение: уже инициализированная константа" ).

Ответ 5

Dir.glob(File.join('path', '**', '*.rb'), &method(:require))

или, альтернативно, если вы хотите указать файлы для загрузки в определенные папки:

Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require))

пояснение:

Dir.glob принимает блок как аргумент.

метод (: require) вернет метод require.

& method (: require) преобразует метод в блок.

Ответ 6

Лучше всего добавить каталог в путь загрузки, а затем 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 }

Ответ 7

Вместо конкатенирования путей, как в некоторых ответах, я использую File.expand_path:

Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file|
  require file
end

Update:

Вместо использования File.dirname вы можете сделать следующее:

Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
  require file
end

Где .. разделяет имя файла __FILE__.

Ответ 8

Dir[File.join(__dir__, "/app/**/*.rb")].each do |file|
  require file
end

Это будет работать рекурсивно на вашей локальной машине и удаленной (как и Heroku), которая не использует относительные пути.

Ответ 9

В Rails вы можете сделать:

Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }

Обновление: Исправлено с предложением @Jiggneshh Gohel удалить косые черты.

Ответ 10

Я опаздываю на вечеринку на несколько лет, но я вроде как это однострочное решение, которое я использовал для получения рельсов, чтобы включить все в app/workers/problems:

Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }

Ответ 11

А как насчет: require_relative *Dir['relative path']?