2009-06-18 11 views
5

Wie können Sie die Hierarchie von Requests anzeigen, die in einer Ruby-App stattfinden?Wie können Sie die vollständige Reihenfolge und Reihenfolge von Requests in einer Ruby-App als Baum verfolgen?

Einige Dateien erfordern Dateien, die zusätzliche Dateien erfordern.

Wenn Sie jedoch eine Anwendung im Debug-Modus ausführen, lösen Sie nur eine Teilmenge der erforderlichen Dateien aus - nur die, die von einer beliebigen Teilmenge der Funktionalität verwendet werden, die Ihre Anwendung zu einem bestimmten Zeitpunkt verwendet.

Wie können Sie eine umfassende Hierarchie aller Anforderungen in einer Anwendung als Baum anzeigen?

Antwort

9

Das Problem ist, dass im Entwicklungsmodus alle Dateien mit load statt require geladen werden, so dass sie bei jeder Anforderung neu geladen werden können. In der Produktion werden sie nur einmal geladen. Mit Ausnahme einiger Framework-Klassen werden die meisten Dateien nur dann geladen, wenn sie zum ersten Mal verwendet werden. Dies geschieht, weil ActiveSupport const_missing überschreibt, um automatisch zu versuchen, unbekannte Konstanten aus Dateien mit dem entsprechenden Namensschema zu laden (ConstantName.to_s.underscore würde require 'constant_name' ergeben). Dies verwirrt natürlich die Hierarchie "erfordern".

Für eine triviale Fall können Sie die folgenden Funktionen zu erfüllen einige Ihrer Bedürfnisse (auch Abhängigkeiten in active_support check out) ändern

$require_level = [] 
    alias :orig_require :require 
    def require(file) 
    puts "#{$require_level.join}#{file}" 
    $require_level << "-" 
    r = orig_require(file) 
    $require_level.pop 
    r 
    end 

    require 'foo' 
    require 'baz' 


[email protected]:~ $ ruby check_requires.rb 
foo 
-bar 
baz 

Viel Glück

EDIT: Erklärung

Was das does erzeugt ein globales Array zum Speichern der Verschachtelungsebene von requires. Der erste puts gibt die erforderliche Datei aus. Dann wird der Verschachtelungsebene ein Strich hinzugefügt. Die Datei wird dann tatsächlich benötigt. Wenn die geladenen Dateiaufrufe erforderlich sind, wird der gesamte Prozess erneut gestartet, außer dass die Verschachtelungsebene 1 tief ist, sodass "- # {Datei}" eingefügt wird. Dieser Vorgang wird wiederholt, außer wenn die Verschachtelungsebene zunimmt, auch die Bindestriche. Nachdem eine Datei und alle zugehörigen Abhängigkeiten geladen wurden, wird require den Bindestrich entfernen, der hinzugefügt wurde, sodass die Verschachtelungsebene in dem Zustand ist, in dem sie sich befand, als die Anforderung gestartet wurde. Dies hält die Baumstruktur genau.

const_missing ist ähnlich wie method_missing. Im Grunde, genau wie wenn Sie AnObject.some_unknown_method aufrufen, ruft ruby ​​AnObject.method_missing(:some_unknown_method) an, bevor ein NoMethodError ausgelöst wird, wobei SomeUnknownConstant einen const_missing(:SomeUnknownConstant) auslöst, bevor ein NameError ausgelöst wird. Rails definiert const_missing so, dass es bestimmte angegebene Pfade nach Dateien durchsucht, die möglicherweise die fehlende Konstante definieren. Es verwendet eine Namenskonvention, um dies zu erleichtern, z. SomeUnknownConstant wird voraussichtlich in some_unknown_constant.rb sein

Es gibt eine Methode zu viel von dieser Schiene Wahnsinn.

+0

Wow. Das ist ein nettes kleines Skript. Lass mich sehen, ob ich herausfinden kann, was du tust. Require_level ist also ein leeres globales Array. Dann alias die require-Methode als orig_require und redefinieren require. Nicht sicher, was deine erste puts-Anweisung tut. Dann fügen Sie einen Strich an das Array an. Dann benötigen Sie die Datei, den letzten Wert aus dem Array Pop (warum stören? Es ist nur ein Strich, nicht wahr? Können Sie nicht einfach "-" drucken?) Dann drucken Sie den Namen der Datei, die Sie benötigt. Es scheint zu funktionieren, ich bin mir nur nicht sicher, wie alles funktioniert. Danke für das Skript. Ich werde es jetzt versuchen. – monkeyman

+0

Auch in Ihrer Antwort habe ich nicht verstanden, was Sie über const_missing meinten. Würde es Ihnen etwas ausmachen, darauf näher einzugehen? – monkeyman

+0

Danke - Dein Skript funktioniert großartig! – monkeyman