97 votes

Ajout d'un répertoire à $LOAD_PATH (Ruby)

J'ai vu deux techniques couramment utilisées pour ajouter le répertoire du fichier en cours d'exécution au $LOAD_PATH (ou $ :). Je vois les avantages de faire cela dans le cas où vous ne travaillez pas avec une gemme. L'une semble plus verbeuse que l'autre, évidemment, mais y a-t-il une raison de choisir l'une plutôt que l'autre ?

La première méthode, verbeuse (pourrait être excessive) :

$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))

et le plus direct, le plus rapide et le plus sale :

$:.unshift File.dirname(__FILE__)

Y a-t-il une raison de choisir l'un plutôt que l'autre ?

2 votes

A légèrement version moins verbeuse de la version verbeuse : File.expand_path(File.dirname(__FILE__)).tap {|pwd| $LOAD_PATH.unshift(pwd) unless $LOAD_PATH.include?(pwd)}

0 votes

Qu'en est-il de la clause "à moins que" ? Comment les deux clauses ci-dessus peuvent-elles être équivalentes ?

0 votes

En tant que personne venue ici pour essayer de comprendre comment l'utiliser, c'est super cryptique. Je ne vois pas d'où vient le nom du répertoire dans les exemples. J'apprécierais que quelqu'un puisse clarifier cela.

0voto

Rubyist Points 1

Il existe une gemme qui vous permettra de configurer votre chemin de chargement avec un code plus joli et plus propre. Regardez ça : https://github.com/nayyara-samuel/load-path .

Il dispose également d'une bonne documentation

0 votes

Qui n'existe apparemment plus

-2voto

Je sais que cela fait longtemps que cette question a été posée pour la première fois, mais j'ai une réponse supplémentaire que je veux partager.

J'ai plusieurs applications Ruby qui ont été développées par un autre programmeur sur plusieurs années, et ils réutilisent les mêmes classes dans les différentes applications bien qu'elles puissent accéder à la même base de données. Comme cela viole la règle DRY, j'ai décidé de créer une bibliothèque de classes qui sera partagée par toutes les applications Ruby. J'aurais pu la placer dans la bibliothèque principale de Ruby, mais cela aurait caché du code personnalisé dans la base de code commune, ce que je ne voulais pas faire.

J'ai eu un problème où j'avais un conflit de nom entre un nom déjà défini "profile.rb", et une classe que j'utilisais. Ce conflit n'était pas un problème jusqu'à ce que j'essaie de créer la bibliothèque de code commune. Normalement, Ruby cherche d'abord dans les emplacements de l'application, puis dans les emplacements $LOAD_PATH.

L'application_controller.rb n'a pas pu trouver la classe que j'ai créée, et a lancé une erreur sur la définition originale parce que ce n'est pas une classe. Comme j'ai supprimé la définition de la classe de la section app/models de l'application, Ruby n'a pas pu la trouver là et l'a cherchée dans les chemins Ruby.

J'ai donc modifié la variable $LOAD_PATH pour y inclure un chemin d'accès au répertoire de la bibliothèque que j'utilisais. Cela peut être fait dans le fichier environment.rb au moment de l'initialisation.

Même avec le nouveau répertoire ajouté au chemin de recherche, Ruby lançait une erreur car il prenait de préférence le fichier défini par le système en premier. Le chemin de recherche dans la variable $LOAD_PATH recherche de préférence les chemins de Ruby en premier.

J'ai donc dû modifier l'ordre de recherche pour que Ruby trouve la classe dans ma bibliothèque commune avant de chercher dans les bibliothèques intégrées.

Ce code l'a fait dans le fichier environment.rb :

Rails::Initializer.run do |config|

* * * * *

path = []
path.concat($LOAD_PATH)
$LOAD_PATH.clear
$LOAD_PATH << 'C:\web\common\lib'
$LOAD_PATH << 'C:\web\common'
$LOAD_PATH.concat(path)

* * * * *

end

Je ne pense pas que vous puissiez utiliser l'une des constructions de codage avancées données précédemment à ce niveau, mais cela fonctionne très bien si vous voulez configurer quelque chose au moment de l'initialisation de votre application. Vous devez conserver l'ordre initial de la variable $LOAD_PATH originale lorsqu'elle est ajoutée à la nouvelle variable, sinon certaines des principales classes Ruby seront perdues.

Dans le fichier application_controller.rb, j'utilise simplement un fichier

require 'profile'
require 'etc' #etc

et cela charge les fichiers de la bibliothèque personnalisée pour l'ensemble de l'application, c'est-à-dire que je n'ai pas besoin d'utiliser les commandes require dans chaque contrôleur.

Pour moi, c'était la solution que je cherchais, et j'ai pensé l'ajouter à cette réponse pour faire passer l'information.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X