La magie du chargement automatique
Je pense que l'option contrôlant les dossiers à partir desquels se fait le chargement automatique a été suffisamment couverte dans d'autres réponses. Cependant, dans le cas où quelqu'un d'autre a des problèmes de chargement alors qu'ils ont vu leurs chemins de chargement automatique modifiés comme requis, cette réponse essaie d'expliquer quelle est la magie derrière ce chargement automatique.
Donc, quand il s'agit de charger des choses à partir de sous-répertoires, il y a un piège ou une convention que vous devez connaître. Parfois, la magie Ruby / Rails (cette fois principalement Rails) peut rendre difficile de comprendre pourquoi quelque chose se passe. Tout module déclaré dans les chemins de chargement automatique ne sera chargé que si le nom du module correspond au nom du répertoire parent. Donc, si vous essayez de mettre lib/my_stuff/bar.rb
quelque chose comme:
module Foo
class Bar
end
end
Il ne sera pas chargé automatiquement. Là encore , si vous renommez le répertoire parent pour foo
ainsi l' hébergement de votre module à la voie: lib/foo/bar.rb
. Ce sera là pour vous. Une autre option consiste à nommer le fichier que vous souhaitez charger automatiquement par le nom du module. De toute évidence, il ne peut y avoir qu'un seul fichier de ce nom. Dans le cas où vous avez besoin de diviser vos fichiers en plusieurs fichiers, vous pouvez bien sûr utiliser ce fichier pour exiger d'autres fichiers, mais je ne le recommande pas, car alors en mode développement et que vous modifiez ces autres fichiers, Rails ne peut pas le faire automatiquement. rechargez-les pour vous. Mais si vous voulez vraiment, vous pouvez avoir un fichier par le nom du module qui spécifie alors les fichiers réels nécessaires pour utiliser le module. Vous pouvez donc avoir deux fichiers: lib/my_stuff/bar.rb
et lib/my_stuff/foo.rb
et le premier étant le même que ci-dessus et le dernier contenant une seule ligne:require "bar"
et cela fonctionnerait tout de même.
PS Je me sens obligé d'ajouter une chose plus importante. Ces derniers temps, chaque fois que je veux avoir quelque chose dans le répertoire lib qui doit être chargé automatiquement, j'ai tendance à penser que si c'est quelque chose que je développe spécifiquement pour ce projet (ce qui est généralement le cas, cela pourrait un jour se transformer en un extrait de code "statique" utilisé dans de nombreux projets ou un sous-module git, etc. auquel cas il devrait certainement se trouver dans le dossier lib) alors peut-être que sa place ne se trouve pas du tout dans le dossier lib. Peut-être que cela devrait être dans un sous-dossier sous le dossier de l'application · J'ai le sentiment que c'est la nouvelle façon de faire les rails. De toute évidence, la même magie opère partout dans les chemins de chargement automatique dans lesquels vous mettez vos trucs, donc c'est bon pour ces choses. Quoi qu'il en soit, ce ne sont que mes réflexions sur le sujet. Vous êtes libre d'être en désaccord. :)
MISE À JOUR: À propos du type de magie ..
Comme l'a souligné Severin dans son commentaire, le noyau "mécanisme de chargement automatique d'un module" fait bien sûr partie de Ruby, mais les trucs de chemins de chargement automatique ne le sont pas. Vous n'avez pas besoin de Rails pour faireautoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. Et lorsque vous essayez de référencer le module Foo pour la première fois, il est chargé pour vous. Cependant, ce que fait Rails, c'est qu'il nous donne un moyen d'essayer de charger automatiquement des choses à partir de dossiers enregistrés et cela a été implémenté de telle sorte qu'il doit supposer quelque chose sur les conventions de dénomination. S'il n'avait pas été implémenté de cette façon, chaque fois que vous faites référence à quelque chose qui n'est pas actuellement chargé, il devra parcourir tous les fichiers de tous les dossiers de chargement automatique et vérifier si l'un d'eux contient ce que vous essayez de référencer. À son tour, cela irait à l'encontre de l'idée du chargement automatique et du chargement automatique. Cependant, avec ces conventions en place, il peut déduire du module / classe que vous essayez de charger où cela pourrait être défini et de le charger.
app/lib
.