2009-07-06 6 views
5

J'ai un code d'initialisation Lisp:Pourquoi doit 'exiger' être évaluée dans une expression distincte pour l'utilisation du paquet

(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*)) 

Pourquoi cette version compilent, alors que cette version:

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

produit une erreur lors de la compilation de fichier dans la 3ème ligne, avec asdf un paquet non reconnu? J'utilise ccl, et (require 'asdf) est documenté comme apportant la version intégrée de ASDF.

Répondre

9

Ce qui suit peut être inexacte à certains égards, mais il est à peu près comme ceci:

Il y a quatre phases que le « moteur » Lisp passe par: temps de lecture, le temps d'expansion macro, temps de compilation, et le temps d'exécution .

Chaque formulaire de premier niveau est entièrement lu en premier. La lecture implique cependant la résolution des symboles respectifs. Comme ASDF n'est pas encore chargé pendant la lecture de votre formulaire eval-when, le symbole asdf:*central-registry* ne peut pas encore être résolu, ce qui produit l'erreur de lecture mentionnée.

4

Voir la réponse de Svante.

Parfois, vous pourriez vouloir contourner ce problème. Ensuite, vous devez rechercher le symbole dans le code à RUNTIME.

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

code ci-dessus peut être utilisé, parce que le symbole asdf: *-registre central * n'est pas utilisé directement, mais leva les yeux vers l'exécution en utilisant le nom du symbole et le nom du package.