Лучший способ требовать все файлы из каталога в ruby? - PullRequest
328 голосов
/ 09 апреля 2009

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

Ответы [ 11 ]

435 голосов
/ 09 апреля 2009

Как насчет:

Dir["/path/to/directory/*.rb"].each {|file| require file }
334 голосов
/ 09 апреля 2009

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

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

Редактировать: На основе комментариев ниже, обновленная версия:

Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }
97 голосов
/ 14 июня 2009

Попробуйте использовать камень require_all:

  1. http://github.com/jarmo/require_all
  2. https://rubygems.org/gems/require_all

Это позволяет вам просто:

require_all 'path/to/directory'
52 голосов
/ 09 февраля 2010
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file| 
  require File.basename(file, File.extname(file))
end

Если вы не удалите расширение, вам может понадобиться один и тот же файл дважды (ruby не поймет, что «foo» и «foo.rb» - это один и тот же файл). Двойной запрос одного и того же файла может привести к ложным предупреждениям (например, «предупреждение: уже инициализированная константа»).

41 голосов
/ 11 февраля 2014
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))

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

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

объяснение:

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

method (: require) вернет требуемый метод.

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

30 голосов
/ 10 апреля 2009

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

Если вам не нужно, чтобы файл требовался более одного раза, или вы просто хотите загрузить содержимое файла, возможно, вместо require следует использовать load. В этом случае используйте load, потому что она лучше отражает то, что вы пытаетесь выполнить. Например:

Dir["/path/to/directory/*.rb"].each {|file| load file }
14 голосов
/ 18 февраля 2014

Вместо объединения путей, как в некоторых ответах, я использую 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__.

13 голосов
/ 19 июня 2011
Dir[File.join(__dir__, "/app/**/*.rb")].each do |file|
  require file
end

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

7 голосов
/ 26 сентября 2014

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

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

Обновление: исправлено с предложением @Jiggneshh Gohel для удаления слешей.

3 голосов
/ 11 июня 2014

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

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

...