Rubyのディレクトリからすべてのファイルを要求する最良の方法は何ですか?
どうですか:
Dir["/path/to/directory/*.rb"].each {|file| require file }
要求を行うファイルに関連するディレクトリの場合(たとえば、libディレクトリ内のすべてのファイルをロードする場合):
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }
編集:以下のコメントに基づいて、更新されたバージョン:
Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }
Require_all gemを試してください:
簡単にできます:
require_all 'path/to/directory'
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file|
require File.basename(file, File.extname(file))
end
拡張子を削除しないと、同じファイルが2回必要になる可能性があります(Rubyは "foo"と "foo.rb"が同じファイルであることを認識しません)。同じファイルを2回要求すると、誤った警告が発生する可能性があります(例:「警告:既に初期化された定数」)。
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)は、メソッドをブロックに変換します。
最良の方法は、ディレクトリをロードパスに追加してから、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 }
いくつかの答えのようにパスを連結する代わりに、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 }
更新:スラッシュを削除するために@Jiggneshh Gohelの提案で修正されました。
私はパーティーに数年遅れていますが、私はRailsにアプリ/労働者/懸念のすべてを含めるために使用したこの1行のソリューションのようなものです:
Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }