web-dev-qa-db-fra.com

Le meilleur moyen d’exiger tous les fichiers d’un répertoire Ruby?

Quel est le meilleur moyen d'exiger tous les fichiers d'un répertoire dans Ruby?

336
Gaetan Dubar

Que diriez-vous:

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

Si c'est un répertoire relatif au fichier qui fait la demande (par exemple, vous voulez charger tous les fichiers du répertoire lib):

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

Edit: D'après les commentaires ci-dessous, une version mise à jour:

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

Essayez le bijou require_all:

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

Cela vous permet simplement:

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

Si vous ne supprimez pas l'extension, il se peut que vous demandiez le même fichier deux fois (Ruby ne réalisera pas que "foo" et "foo.rb" sont le même fichier). Exiger le même fichier deux fois peut entraîner de fausses alertes (par exemple, "warning: constante déjà initialisée").

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

ou bien, si vous souhaitez définir la portée des fichiers à charger dans des dossiers spécifiques:

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

explication:

Dir.glob prend un bloc comme argument.

method (: require) retournera la méthode require.

& method (: require) convertira la méthode en bloc.

42
metakungfu

La meilleure méthode consiste à ajouter le répertoire au chemin de chargement, puis require le nom de base de chaque fichier. Cela est dû au fait que vous souhaitez éviter de demander accidentellement le même fichier deux fois - souvent pas le comportement souhaité. Que le fichier soit chargé ou non dépend de si require a déjà vu le chemin d'accès passé. Par exemple, cette simple session irb montre que vous pouvez par erreur demander et charger le même fichier deux fois.

$ 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

Notez que les deux premières lignes renvoient true, ce qui signifie que le même fichier a été chargé les deux fois. Lorsque des chemins sont utilisés, même s'ils pointent au même emplacement, require ne sait pas que le fichier était déjà requis.

Ici, à la place, nous ajoutons un répertoire au chemin de chargement et demandons ensuite le nom de base de chaque fichier * .rb.

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

Si vous ne vous souciez pas du fichier requis plus d'une fois, ou si votre intention est simplement de charger le contenu du fichier, peut-être que load devrait être utilisé à la place de require. Utilisez load dans ce cas, car il exprime mieux ce que vous essayez d'accomplir. Par exemple:

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

Au lieu de concaténer des chemins comme dans certaines réponses, j'utilise File.expand_path:

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

Mise à jour:

Au lieu d'utiliser File.dirname, vous pouvez procéder comme suit:

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

.. supprime le nom de fichier de __FILE__.

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

Cela fonctionnera de manière récursive sur votre machine locale et sur une télécommande (comme Heroku) qui n’utilise pas de chemins relatifs.

13
user470069

Dans Rails, vous pouvez faire:

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

Mise à jour: Corrigé avec la suggestion de @Jiggneshh Gohel de supprimer les barres obliques.

7
Dan Kohn

Je suis avec quelques années de retard dans la soirée, mais j'aime un peu cette solution à une ligne que j'avais l'habitude de faire Rails pour tout inclure dans les applications/travailleurs/préoccupations:

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

3
Jazz