2014-11-23 10 views
6

64-Bit-Windows-7
Clozure Common Lisp Version 1.9 WindowsX8632
Emacs 24.3.1
Slime Changelog Datum 2014-06 zu arbeiten -17
Common Lisp: Wie (in-Package ...) vom Emacs Slime

ich habe ein Beispiel .lisp Datei, die beginnt wie folgt:

(ql:quickload 'qt) 
(in-package "QT") 

der Rest des Programms zeigt ein Dialogfeld. Wenn ich dies über die Befehlszeile ausführen, wx86cl -load helloqt.lisp scheint es gut zu funktionieren. Wenn ich dies von Emacs Slime (C-x C-k) ausführen, heißt es dort gibt es kein Paket "QT". Aber wenn ich zuerst die erste Zeile einzeln auswerte (C-x C-e) dann kann ich die ganze Sache kompilieren und es funktioniert, modulo die normalen Probleme der Versuch, einen QT-Thread aus Slime unter Windows zu starten.

Wie mache ich es so, dass ich die Datei von Emacs kompilieren/ausführen kann, ohne zuerst die erste Zeile manuell auswerten zu müssen?

Auch warum ändert (in-package ...) das aktuelle Paket in der Slime-Sitzung nicht? Ich muss es manuell ändern, wenn ich mit dem Paketinhalt interagieren möchte.

+0

Sehr ähnliche Fragen wurden bereits beantwortet. Dies wird nicht das letzte Mal sein. Ich habe ein Tag 'eval-when' hinzugefügt. –

Antwort

5

Wenn Sie die Datei als Ganzes kompilieren, wird sie zuerst als Ganzes gelesen. Zu diesem Zeitpunkt wurde noch keiner davon ausgewertet, daher ist das Paket QT noch nicht definiert.

Sie können entweder eval-when verwenden, um etwas zu einem früheren Zeitpunkt auszuwerten, oder eine Systemdefinitionsfunktion verwenden (ASDF ist heutzutage vorherrschend), um Ihr System in der richtigen Reihenfolge zu laden.

Eval-when:

Beachten Sie, dass Sie in der Regel nicht in der Bibliothek Paketen vertrödeln sollen aber Ihr eigenes, neues Paket definieren Sie den Code halten:

(eval-when (:compile-toplevel :load-toplevel :execute) 
    (ql:quickload '#:qt)) 

(defpackage #:qt-example 
    (:use #:qt)) 

(in-package #:qt-example) 

;; your code here 

(Falls Sie sich fragen, , defpackage, defun, defclass usw. sind speziell entworfene Makros, die zu einer Form innerhalb eines solchen eval-when erweitern.)

Dies ist manchmal in Ordnung für kleine einmalige Skripte. Für Systeme von einer nennenswerten Größe, vor allem, sobald sie mehr als eine Quelldatei haben, verwenden Sie ASDF:

;;;; qt-example.asd 

(in-package #:cl-user) 

(asdf:defsystem #:qt-experiments 
    :description "Some experiments with QT." 
    :serial t 
    :components ((:file "package") 
       (:file "qt-example")) 
    :depends-on (#:qt)) 

;;;; package.lisp 

(defpackage #:qt-example 
    (:use #:qt)) 

;;;; qt-example.lisp 

(in-package #:qt-example) 

ASDF kommt mit den meisten Open-Source-Common Lisp-Implementierungen. Möglicherweise müssen Sie die ASDF-Registrierung einrichten. Ich mag alle meine Projekte vor Ort ein oder zwei Basisverzeichnisse haben, so dass ich nur folgendes in ~/.config/common-lisp/source-registry.conf setzen können:

(:source-registry 
    (:tree (:home "devel")) 
    (:tree (:home "src")) 
    :inherit-configuration) 

Dann ASDF alle Systeme unter diesen Verzeichnissen definiert findet. In SLIME können Sie einfach ,load-system oder ,open-system von der REPL mit dem Systemnamen zum Laden verwenden. öffne alle Dateien darin und lade sie optional.

Wenn man aus einer Datei ein einzelnes Toplevel-Formular (mit C-c C-c) kompiliert, schaut SLIME von dort nach einem in-package Formular zurück, um herauszufinden, welches Paket es annehmen soll. Normalerweise sollten Sie nur eine einzelne in-package Form pro Datei an der Spitze haben.

Eine häufig nützliche Abkürzung ist C-c ~ in Lisp-Quelldateien, die die REPL in das Verzeichnis der Datei und das effektive Paket am Punkt schaltet.