Quelle est la meilleure façon d'exiger tous les fichiers d'un répertoire dans ruby?
Quelle est la meilleure façon d'exiger tous les fichiers d'un répertoire dans ruby?
Réponses:
Que diriez-vous:
Dir["/path/to/directory/*.rb"].each {|file| require file }
require
n'est pas confondu par la présence ou l'absence de l' .rb
extension. Testé sur IRM 1.8.7-p374, 2.1.5 et 2.2.0 testé. Cette légende urbaine vient de Rails, où le chargement automatique "intelligent" a montré le comportement qu'il décrit dans les anciennes versions (et peut toujours l'exposer).
S'il s'agit d'un répertoire relatif au fichier qui fait l'exigence (par exemple, vous voulez charger tous les fichiers dans le répertoire lib):
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }
Modifier: sur la base des commentaires ci-dessous, une version mise à jour:
Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
__dir__
place de File.dirname(__FILE__)
.
require_relative
pour exiger tous les fichiers d'un répertoire?
Essayez la gemme require_all:
Il vous permet simplement:
require_all 'path/to/directory'
require_all
la résolution des dépendances cycliques contourne un problème dans votre code source: vous avez des fichiers source Ruby qui ne nécessitent pas leurs dépendances. Cela ferme la porte au chargement du scalpel, vous engageant au chargement tout ou rien. Ce n'est pas un problème dans les petites bibliothèques, mais c'est une décision que vous devriez prendre consciemment.
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file|
require File.basename(file, File.extname(file))
end
Si vous ne supprimez pas l'extension, vous pourriez finir par exiger le même fichier deux fois (ruby ne réalisera pas que "foo" et "foo.rb" sont le même fichier). Le fait d'exiger deux fois le même fichier peut entraîner de faux avertissements (par exemple "avertissement: constante déjà initialisée").
require "foo.rb"; require "foo";
ne se chargera foo.rb
qu'une seule fois.
require
n'est pas dérouté par la présence ou l'absence de l' .rb
extension. Testé sur IRM 1.8.7-p374, 2.1.5 et 2.2.0. Cette légende urbaine vient de Rails, où le chargement automatique "intelligent" a montré le comportement décrit dans les anciennes versions (et peut encore l'exposer).
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))
ou bien, si vous souhaitez étendre les 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.
La méthode (: require) renverra la méthode require.
& method (: require) convertira la méthode en bloc.
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )
élimine la dépendance à la plate-forme (comme «/» ou «\»). Fonctionne bien. Merci.
La meilleure façon est d'ajouter le répertoire au chemin de chargement puis require
le nom de base de chaque fichier. En effet, vous voulez éviter d'exiger accidentellement le même fichier deux fois - souvent pas le comportement souhaité. Le chargement ou non d'un fichier dépend du fait que require
le chemin lui a déjà été transmis auparavant. Par exemple, cette simple session IRB montre que vous pouvez par erreur exiger et charger deux fois le même fichier.
$ 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 si les chemins pointent vers le 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 qu'il contient.
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 que le fichier soit requis plusieurs fois, ou si votre intention est simplement de charger le contenu du fichier, vous load
devriez peut -être utiliser à la place de require
. Utilisez la charge dans ce cas, car elle exprime mieux ce que vous essayez d'accomplir. Par exemple:
Dir["/path/to/directory/*.rb"].each {|file| load file }
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 effectuer les opérations suivantes:
Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
require file
end
Où ..
supprime le nom de fichier de __FILE__
.
File.expand_path
Rails.root.join
réponses fonctionnent également si vous êtes dans les rails.
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 pour supprimer les barres obliques.
Rails.root.join('/lib')
ne génère pas le chemin correct. J'ai trouvé que celui-ci fonctionnait correctement:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
Et qu'en est-il de require_relative *Dir['relative path']
:?
require_relative *Dir['*.rb']
fonctionne, s'il n'y a qu'un seul ruby-script. Mais si plusieurs scripts rubis sont trouvés, vous obtenezrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)