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.
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.
1 votes
Utilisation de
__dir__
(à partir de Ruby 2.0) peut rendre n'importe lequel de ces éléments plus concis.