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

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

11 ответов


Как насчет:

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

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

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

Edit: на основе комментариев ниже, обновленная версия:

Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }

попробуйте require_all gem:

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

Это можно просто:

require_all 'path/to/directory'

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 }


а как же:require_relative *Dir['relative path']?