Selon le Pickaxe, l'extension .rb est facultative. Techniquement, cela change la signification: "require 'foo.rb'" requires foo.rb, alors que "require 'foo'" pourrait nécessiter foo.rb, foo.so ou foo.dll.
Sam Stokes
28
Il y a un subtil piège à ne pas supprimer l'extension. Si une autre partie des appels de code nécessite «foo», ruby chargera à nouveau le même fichier, ce qui peut entraîner des erreurs parasites. J'ai ajouté ma propre réponse qui explique cela et montre comment supprimer l'extension.
Cela peut être évident, mais il vaut la peine de noter que la suppression du .rb nécessitera également tous les fichiers non .rb dans le répertoire, ce qui peut ne pas être souhaité.
user2398029
10
La suggestion de @ PeteHodgson est inexacte. Ruby's requiren'est pas confondu par la présence ou l'absence de l' .rbextension. 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).
sheldonh
345
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):
Vous pouvez également ajouter tous les répertoires enfants comme celui-ciDir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
jspooner
62
Il est probablement plus sûr d'utiliser File.join plutôt que de faire des hypothèses sur les barres obliques avant / arrière:Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
Chris
6
Il y a aussi require_relative
maasha
30
Si vous utilisez> = ruby 2.0, vous pouvez utiliser à la __dir__place de File.dirname(__FILE__).
Christian Bankester
3
@maasha Comment utilisez-vous require_relativepour exiger tous les fichiers d'un répertoire?
J'avais besoin d'inclure tous mes modèles ActiveRecord, la gemme require_all a compris toutes les dépendances et les a parfaitement requises. Merci!
panupan
2
@panupan Sachez simplement que require_allla 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.
sheldonh
Cela n'a pas de sens de gonfler votre application avec des gemmes que vous pouvez simplement remplacer par une ligne de code. Cela augmente le temps de chargement de votre application et induit plus de bugs à long terme.
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").
Est-ce vraiment le cas? La documentation dit: Une fonctionnalité ne sera pas chargée si son nom apparaît déjà dans $ ". Le nom du fichier est converti en un chemin absolu, donc" require 'a'; require './a' "ne chargera pas a.rb deux fois. ruby-doc.org/core/classes/Kernel.html#M001418
Derek
13
Mes tests montrent la même chose que Derek a dit: require "foo.rb"; require "foo";ne se chargera foo.rbqu'une seule fois.
Rene Saarsoo
@ PeteHodgson- Pouvez-vous sauvegarder cela?
Yarin
4
Non. Ruby requiren'est pas dérouté par la présence ou l'absence de l' .rbextension. 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).
Ceci est un beau code. J'adore la façon dont il n'y a pas de blocs visibles.
Nate Symer
1
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.
Ivan Black
30
La meilleure façon est d'ajouter le répertoire au chemin de chargement puis requirele 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 requirele 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.
Notez que les deux premières lignes renvoient truece 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, requirene 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 loaddevriez 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:
Puisque Rails.rootc'est une Pathnameinstance, vous pouvez le faire dans n'importe quel environnement Ruby, pas seulement Rails (NB Rails.root.join('lib/ext/*.rb')est un peu plus agréable)
DMKE
Merci pour la recommandation; J'ai modifié pour inclure votre commentaire.
Dan Kohn
Utiliser une barre oblique (/) pour les sous-répertoires sous Rails.root, par exemple, 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 }
Jignesh Gohel
@Jiggneshh Gohel J'ai supprimé les barres obliques comme vous l'avez suggéré, merci.
Dan Kohn
3
J'ai quelques années de retard pour la fête, mais j'aime un peu cette solution à une ligne que j'utilisais pour que les rails incluent tout dans l'application / les travailleurs / les préoccupations:
D'accord, mais dans mon exemple, ce n'est pas le cas. Le '*' change l'arité en 1. Il fonctionne comme un appel multiple à require_relative.
Aleksander
1
Le '*' change l'arité en 1 - Que voulez-vous dire par là? 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)
Réponses:
Que diriez-vous:
la source
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):
Modifier: sur la base des commentaires ci-dessous, une version mise à jour:
la source
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
__dir__
place deFile.dirname(__FILE__)
.require_relative
pour exiger tous les fichiers d'un répertoire?Essayez la gemme require_all:
Il vous permet simplement:
la source
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.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").
la source
require "foo.rb"; require "foo";
ne se chargerafoo.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).ou bien, si vous souhaitez étendre les fichiers à charger dans des dossiers spécifiques:
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.
la source
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 querequire
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.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.
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 derequire
. Utilisez la charge dans ce cas, car elle exprime mieux ce que vous essayez d'accomplir. Par exemple:la source
Au lieu de concaténer des chemins comme dans certaines réponses, j'utilise
File.expand_path
:Mise à jour:
Au lieu d'utiliser,
File.dirname
vous pouvez effectuer les opérations suivantes:Où
..
supprime le nom de fichier de__FILE__
.la source
File.expand_path
Rails.root.join
réponses fonctionnent également si vous êtes dans les rails.Cela fonctionnera récursivement sur votre machine locale et une télécommande (comme Heroku) qui n'utilise pas de chemins relatifs.
la source
Dans Rails, vous pouvez faire:
Mise à jour: corrigé avec la suggestion de @Jiggneshh Gohel pour supprimer les barres obliques.
la source
Rails.root
c'est unePathname
instance, vous pouvez le faire dans n'importe quel environnement Ruby, pas seulement Rails (NBRails.root.join('lib/ext/*.rb')
est un peu plus agréable)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 }
J'ai quelques années de retard pour la fête, mais j'aime un peu cette solution à une ligne que j'utilisais pour que les rails incluent tout dans l'application / les travailleurs / les préoccupations:
Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }
la source
Et qu'en est-il de
require_relative *Dir['relative path']
:?la source
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)