2014-11-23 9 views
6

a 64 bit di Windows 7
Clozure Common Lisp versione 1.9 WindowsX8632
Emacs 24.3.1
Slime data changelog 2014-06 -17
Common Lisp: Come arrivare (in-package ...) di lavorare all'interno di Emacs Slime

ho un esempio .lisp file di che inizia come segue:

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

il resto del programma mostra una finestra di dialogo. Quando lo eseguo dalla riga di comando, wx86cl -load helloqt.lisp sembra funzionare correttamente. Quando lo eseguo da Emacs Slime (C-x C-k) dice che non c'è il pacchetto "QT". Tuttavia, se prima valutiamo la prima riga individualmente (C-x C-e), allora posso compilare il tutto e funziona, modulo i normali problemi di provare a eseguire un thread QT all'interno di Slime su Windows.

Come posso fare in modo che possa compilare/eseguire il file da emacs senza dover prima valutare manualmente la prima riga?

Inoltre, perché lo (in-package ...) non modifica il pacchetto corrente nella sessione Slime? Devo cambiarlo manualmente se voglio interagire con il contenuto del pacchetto.

+0

Domande molto simili sono già state risolte. Questa non sarà l'ultima volta. Ho aggiunto un tag 'eval-when'. –

risposta

5

Quando si compila il file nel suo complesso, viene prima letto nel suo complesso. A quel tempo, nessuno di questi è ancora stato valutato, quindi il pacchetto QT non è ancora stato definito.

È possibile utilizzare eval-when per valutare qualcosa in un momento precedente oppure utilizzare una funzione di definizione del sistema (attualmente ASDF è predominante) per caricare il sistema nell'ordine corretto.

Eval-when:

Nota che di solito non si dovrebbe impazzire in pacchetti di libreria, ma definire il proprio pacchetto, fresco di tenere il tuo codice:

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

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

(in-package #:qt-example) 

;; your code here 

(Nel caso vi state chiedendo , defpackage, defun, defclass ecc. Sono macro appositamente progettate che si espandono in un modulo all'interno di tale .)

Questo è a volte OK per piccoli script one-off. Per i sistemi di qualsiasi dimensione degna di nota, in particolare, non appena hanno più di un file di origine, utilizzare 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 viene fornito con la maggior parte delle implementazioni open-source Common Lisp. Potrebbe essere necessario configurare il registro ASDF. Mi piace avere una o due basi directory per tutti i miei progetti locali, in modo che posso solo mettere quanto segue in ~/.config/common-lisp/source-registry.conf:

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

Poi ASDF trova tutti i sistemi di seguito definiti tali directory. In SLIME, è sufficiente utilizzare ,load-system o ,open-system dal REPL con il nome del sistema per caricarlo, risp. apri tutti i file, opzionalmente caricandolo.

Quando si compila un modulo di un unico livello (utilizzando C-c C-c) da un file, SLIME guarda indietro da lì per un modulo in-package per scoprire quale pacchetto deve assumere. Convenzionalmente, si dovrebbe avere un solo modulo in-package per file, nella parte superiore.

Un collegamento comunemente utile è C-c ~ in file sorgente Lisp, che commuta il REPL nella directory del file e il pacchetto effettivo nel punto.