it-swarm.com.de

Beste Weg, um alle Dateien aus einem Verzeichnis in Ruby zu fordern?

Was ist der beste Weg, um alle Dateien aus einem Verzeichnis in Ruby?

336
Gaetan Dubar

Wie wäre es mit:

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

Wenn es sich um ein Verzeichnis relativ zu der Datei handelt, die die Anforderung erfüllt (z. B. Sie möchten alle Dateien im lib-Verzeichnis laden):

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

Edit: Basierend auf den Kommentaren unten eine aktualisierte Version:

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

Probieren Sie das Juwel require_all aus:

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

Damit können Sie einfach:

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

Wenn Sie die Erweiterung nicht entfernen, benötigen Sie möglicherweise zweimal dieselbe Datei (Ruby erkennt nicht, dass "foo" und "foo.rb" dieselbe Datei sind). Das zweimalige Anfordern derselben Datei kann zu falschen Warnungen führen (z. B. "Warnung: Konstante bereits initialisiert").

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

oder alternativ, wenn Sie die Dateien in bestimmte Ordner laden möchten:

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

Erklärung:

Dir.glob nimmt einen Block als Argument.

method (: require) gibt die require-Methode zurück.

& method (: require) konvertiert die Methode in einen Block.

42
metakungfu

Am besten fügen Sie das Verzeichnis dem Ladepfad und dann require den Basisnamen jeder Datei hinzu. Dies liegt daran, dass Sie vermeiden möchten, dass dieselbe Datei versehentlich zweimal benötigt wird - häufig nicht das beabsichtigte Verhalten. Ob eine Datei geladen wird oder nicht, hängt davon ab, ob require den zuvor übergebenen Pfad erkannt hat. Diese einfache irb-Sitzung zeigt beispielsweise, dass Sie aus Versehen dieselbe Datei zweimal anfordern und laden können.

$ 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

Beachten Sie, dass die ersten beiden Zeilen true zurückgeben, was bedeutet, dass dieselbe Datei beide Male geladen wurde. Wenn Pfade verwendet werden, weiß require nicht, dass die Datei bereits erforderlich war, auch wenn die Pfade auf denselben Speicherort verweisen.

Hier fügen wir stattdessen ein Verzeichnis zum Ladepfad hinzu und fordern dann den Basisnamen jeder * .rb-Datei an.

dir = "/path/to/directory"
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }

Wenn Sie sich nicht darum kümmern, dass die Datei mehrmals benötigt wird, oder wenn Sie nur den Inhalt der Datei laden möchten, sollten Sie möglicherweise load anstelle von require verwenden. Verwenden Sie in diesem Fall load, da dies besser zum Ausdruck bringt, was Sie erreichen möchten. Zum Beispiel:

Dir["/path/to/directory/*.rb"].each {|file| load file }
30
Ryan McGeary

Anstatt Pfade wie in einigen Antworten zu verketten, verwende ich File.expand_path:

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

pdate:

Anstelle von File.dirname Sie könnten Folgendes tun:

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

Wo .. entfernt den Dateinamen von __FILE__.

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

Dies funktioniert rekursiv auf Ihrem lokalen Computer und einem Remote-Computer (wie Heroku), der keine relativen Pfade verwendet.

13
user470069

In Rails können Sie Folgendes tun:

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

Update: Korrigiert mit dem Vorschlag von @Jiggneshh Gohel, Schrägstriche zu entfernen.

7
Dan Kohn

Ich bin ein paar Jahre zu spät zur Party, aber ich mag diese einzeilige Lösung, die ich verwendet habe, um Rails) alles in App/Worker/Anliegen aufzunehmen:

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

3
Jazz