Wie sind require
und require_dependency
anders?
Wie können require_dependency
Klassen in der Entwicklung automatisch neu geladen werden, aber require
nicht?
Ich habe mich in den ActiveSupport::Dependencies
Code von Rails und dispatcher.rb vertieft. Was ich in require_dependency
's Code gesehen habe, ist, dass es im Grunde die Konstanten zu einem autoloaded_constants
Array hinzufügt . Es wird jedoch clear_application
nach jeder Anforderung im Dispatcher gelöscht .
Kann jemand eine klare Erklärung geben oder mich auf einige Ressourcen hinweisen, die helfen werden?
Antworten:
require
(und sein Cousinload
) sind Kernmethoden von Ruby.require_dependency
ist eine Methode, mit der Rails das Problem des Abhängigkeitsmanagements lösen kann. Kurz gesagt, Rails kann Klassen im Entwicklungsmodus neu laden, sodass Sie den Server nicht jedes Mal neu starten müssen, wenn Sie eine Codeänderung vornehmen. Das Rails-Framework erstelltrequire_dependency
Ihren Code, damit er ihn verfolgen und neu laden kann, wenn Änderungen vorgenommen werden. Der Standard Rubyrequire
macht das nicht. Als App- (oder Plugin- / Engine-) Entwickler sollten Sie sich keine Sorgen machen müssen,require_dependency
da dies rein intern für Rails ist.Die Magie des Ladevorgangs der Rails-Klasse liegt im ActiveSupport :: Dependencies-Modul. Dieser Code erweitert das Standardverhalten von Ruby, damit Code in Ihrer Rails-App Module (einschließlich Klassen, die von Module erben) automatisch unter Verwendung der Pfad- und Dateinamenkonventionen von Rails lädt. Dadurch muss der Programmierer seinen Code nicht mehr mit
require
Aufrufen verunreinigen, wie Sie es in einer einfachen Ruby-Anwendung tun würden.Anders ausgedrückt: Auf diese Weise können Sie
class Admin::User
innerhalb der Datei definierenapp/models/admin/user.rb
und Rails wissen lassen, wovon Sie sprechen, wenn SieAdmin::User.new
von einem anderen Teil der Anwendung wie einem Controller aus aufrufen . Ohne ActiveSupport :: Dependencies müssten Sie alles,require
was Sie benötigen , manuell ausführen .Wenn Sie aus einer statisch typisierten Sprache wie C #, Java usw. stammen, ist dies möglicherweise eine Überraschung: Der Rails-Code wird erst geladen, wenn er benötigt wird. Beispielsweise ist eine
User
Modellklasse nicht definiert unduser.rb
wird erst geladen, nachdem Sie versucht haben, sie aufzurufenUser.whatever_method_here
. Rails verhindert, dass Ruby sich über diese fehlende Konstante beschwert, lädt Code fürUser
und ermöglicht Ruby, wie gewohnt fortzufahren.Obwohl ich nicht für Ihr spezifisches Bedürfnis sprechen kann, wäre ich sehr überrascht, wenn Sie die
require_dependency
Methode tatsächlich innerhalb eines Plugins oder einer Engine verwenden müssten . Wenn Sie die Rails-Konventionen befolgen, sollten Sie $ LOAD_PATH auch nicht von Hand anpassen müssen. Dies ist nicht "der Rails-Weg".In der Welt von Ruby und auch Rails ist Einfachheit und Klarheit der Schlüssel. Wenn Sie nur ein Plugin oder eine Engine schreiben möchten und bereits tief in die Interna eintauchen, können Sie Ihr Problem aus einem anderen Blickwinkel betrachten. Mein Bauch sagt mir, dass Sie vielleicht versuchen, etwas zu tun, das unnötig kompliziert ist. Aber andererseits habe ich keine Ahnung, was Sie genau tun !! :) :)
quelle
require_dependency
ist in einer Engine nützlich, wenn Sie eine Klasse, die nicht in Ihrer Engine definiert ist (z. B. in einer anderen Engine oder Rails-App), erneut öffnen und neu laden möchten. In diesem Fall funktioniert so etwas:# 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
quelle