2009-07-06 3 views
5

ich einige Lisp Initialisierungscode haben:Warum müssen 'require' in einem separaten Ausdruck ausgewertet des Pakets verwenden

(eval-when (:compile-toplevel :load-toplevel :execute) 
    (require 'asdf)) 

(eval-when (:compile-toplevel :load-toplevel :execute) 
    (push #p"c\:\\lisp\\clsql-4.0.4\\" asdf:*central-registry*)) 

Warum diese Version kompilieren, während diese Version:

(eval-when (:compile-toplevel :load-toplevel :execute) 
    (require 'asdf) 
    (push #p"c\:\\lisp\\clsql-4.0.4\\" asdf:*central-registry*)) 

erzeugt einen Fehler während der Kompilierdatei in der 3. Zeile, mit asdf ein unerkanntes Paket?

Ich benutze ccl, und (benötigen 'asdf) ist dokumentiert als bringen die integrierte Version von ASDF.

Antwort

9

Folgendes kann in einigen Details ungenau sein, aber es ist in etwa wie folgt aus:

Es gibt vier Phasen, die die Lisp „Motor“ geht durch: Zeit, Makro Expansionszeit, kompilieren Zeit, lesen und Zeit laufen .

Jedes Formular der obersten Ebene wird zuerst vollständig eingelesen. Das Lesen beinhaltet jedoch die Auflösung der jeweiligen Symbole. Da ASDF zum Zeitpunkt des Auslesens Ihres Formulars eval-when noch nicht geladen ist, kann das Symbol asdf:*central-registry* noch nicht aufgelöst werden, was zu dem erwähnten Lesefehler führt.

4

Siehe die Antwort von Svante.

Manchmal möchten Sie vielleicht dies umgehen. Dann müssen Sie das Symbol im Code unter RUNTIME nachschlagen.

(push somepath (symbol-value (find-symbol "*CENTRAL-REGISTRY*" "ASDF"))) 

Above-Code kann verwendet werden, da das Symbol asdf: * Zentralregister * nicht direkt verwendet wird, aber sah zur Laufzeit mit den Symbolnamen und den Namen des Pakets.

Verwandte Themen