En quoi require
et require_dependency
Sont-ils différents?
Comment require_dependency
Peut-il recharger automatiquement les classes en développement mais require
ne peut pas?
J'ai creusé dans le code ActiveSupport::Dependencies
Et dispatcher.rb de Rails. Ce que j'ai vu dans le code de require_dependency
, C'est qu'il ajoute essentiellement les constantes à un tableau autoloaded_constants
. Mais il est effacé dans clear_application
À l'intérieur du répartiteur après chaque demande.
Quelqu'un peut-il donner une explication claire ou me diriger vers des ressources qui vous aideront?
require
(et son cousin load
) sont les principales méthodes Ruby. require_dependency
est une méthode qui aide Rails à gérer le problème de la gestion des dépendances. Bref, elle permet à Rails de recharger les classes en mode développement pour que vous ne pas besoin de redémarrer le serveur chaque fois que vous apportez un changement de code. Le framework Rails va require_dependency
votre code pour qu'il puisse le suivre et le recharger lorsque des modifications sont apportées. Le standard Ruby require
ne fait pas cela. En tant que développeur d'application (ou de plugin/moteur), vous ne devriez pas avoir à vous soucier de require_dependency
car cela est purement interne à Rails.
La magie du processus de chargement de classe Rails se trouve dans le module ActiveSupport :: Dependencies. Ce code étend le comportement par défaut Ruby pour autoriser le code à l'intérieur de votre Rails app pour charger automatiquement les modules (y compris les classes qui héritent de Module) en utilisant le chemin d'accès et les conventions de dénomination des fichiers. Cela évite au programmeur de surcharger son code d'appels require
comme vous serait dans une simple Ruby application.
En d'autres termes, cela vous permet de définir class Admin::User
à l'intérieur du fichier app/models/admin/user.rb
et avoir Rails sait de quoi vous parlez lorsque vous appelez Admin::User.new
d'une autre partie de l'application comme un contrôleur. Sans ActiveSupport :: Dépendances impliquées, vous devrez manuellement require
tout ce dont vous avez besoin.
Si vous venez d'un langage de type statique comme C #, Java, etc., cela pourrait être une surprise: Rails n'est pas chargé tant qu'il n'est pas nécessaire. Par exemple, un User
la classe de modèle n'est pas définie et user.rb
n'est chargé qu'après avoir essayé d'appeler User.whatever_method_here
. Rails empêche Ruby de se plaindre de cette constante manquante, charge le code pour User
, puis autorise Ruby = pour continuer comme d'habitude.
Bien que je ne puisse pas parler pour votre besoin spécifique, je serais très surpris si vous aviez réellement besoin d'utiliser le require_dependency
méthode depuis un plugin ou un moteur. Si vous suivez les conventions Rails, vous ne devriez pas non plus avoir à modifier manuellement $ LOAD_PATH. Ce n'est pas "la méthode Rails").
Dans le monde de Ruby et aussi Rails la simplicité et la clarté sont la clé. Si tout ce que vous voulez faire est d'écrire un plugin ou un moteur et vous plongez déjà profondément) en interne alors vous pouvez envisager d'aborder votre problème sous un angle différent. Mon instinct me dit que vous essayez peut-être de faire quelque chose qui est inutilement compliqué. Mais là encore, je n'ai aucune idée de ce que vous faites exactement !! :)
require_dependency
est utile dans un moteur lorsque vous souhaitez rouvrir une classe qui n'est pas définie dans votre moteur (par exemple dans un autre moteur ou Rails app) et la faire recharger. Dans ce cas quelque chose comme ça fonctionne:
# app/controllers/my_engine/documents_controller.rb
require_dependency MyEngine::Engine.root.join('app', 'controllers', 'my_engine', 'documents_controller').to_s
module MyEngine
class DocumentsController
def show
render :text => 'different'
end
end
end