web-dev-qa-db-ja.com

ルビーのディレクトリからすべてのファイルを要求する最良の方法は?

Rubyのディレクトリからすべてのファイルを要求する最良の方法は何ですか?

329
Gaetan Dubar

どうですか:

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

要求を行うファイルに関連するディレクトリの場合(たとえば、libディレクトリ内のすべてのファイルをロードする場合):

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

編集:以下のコメントに基づいて、更新されたバージョン:

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

Require_all gemを試してください:

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

簡単にできます:

require_all 'path/to/directory'
97
Tony Arcieri
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file| 
  require File.basename(file, File.extname(file))
end

拡張子を削除しないと、同じファイルが2回必要になる可能性があります(Rubyは "foo"と "foo.rb"が同じファイルであることを認識しません)。同じファイルを2回要求すると、誤った警告が発生する可能性があります(例:「警告:既に初期化された定数」)。

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

または、特定のフォルダーにロードするファイルをスコープする場合:

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

説明:

Dir.glob はブロックを引数として受け取ります。

method(:require) requireメソッドを返します。

&method(:require)は、メソッドをブロックに変換します。

41
metakungfu

最良の方法は、ディレクトリをロードパスに追加してから、requireを各ファイルのベース名に追加することです。これは、誤って同じファイルを2回要求することを避けたいためです-多くの場合、意図した動作ではありません。ファイルがロードされるかどうかは、requireが以前に渡されたパスを見たかどうかに依存します。たとえば、この単純なirbセッションは、同じファイルを誤って2回要求してロードできることを示しています。

$ 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

最初の2行はtrueを返すことに注意してください。これは、同じファイルが両方の時間にロードされたことを意味します。パスが使用されている場合、パスが同じ場所を指していても、requireはファイルがすでに必要であることを知りません。

代わりに、ロードパスにディレクトリを追加し、その中の各* .rbファイルのベース名を要求します。

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 }
30
Ryan McGeary

いくつかの答えのようにパスを連結する代わりに、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__のファイル名を削除します。

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

これは、ローカルマシンと相対パスを使用しないリモート(Herokuのような)で再帰的に動作します。

13
user470069

Railsでは、次のことができます。

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

更新:スラッシュを削除するために@Jiggneshh Gohelの提案で修正されました。

7
Dan Kohn

私はパーティーに数年遅れていますが、私はRailsにアプリ/労働者/懸念のすべてを含めるために使用したこの1行のソリューションのようなものです:

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

3
Jazz