8

64 位 Windows 7
Clozure Common Lisp 版本 1.9 WindowsX8632
Emacs 24.3.1
Slime 更新日志日期 2014-06-17

我有一个示例 .lisp 文件,其开头如下:

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

程序的其余部分显示一个对话框。当我从命令行运行它时,wx86cl -load helloqt.lisp它似乎工作正常。当我从 Emacs Slime ( C-x C-k) 运行它时,它说没有包“QT”。C-x C-e但是,如果我首先单独评估第一行(

如何制作它,以便我可以从 emacs 编译/运行文件,而不必先手动评估第一行?

另外,为什么不在(in-package ...)Slime 会话中更改当前包?如果我想与包内容交互,我必须手动更改它。

4

1 回答 1

6

当您将文件作为一个整体编译时,它首先被作为一个整体读取。那时还没有评估过,所以QT还没有定义包。

您可以使用eval-when在更早的时间评估某些内容,或者使用系统定义工具(ASDF 现在占主导地位)以正确的顺序加载您的系统。

Eval-when

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

(in-package #:qt)

请注意,您通常不应该在库包中乱七八糟,而是定义自己的新包来保存您的代码:

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

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

(in-package #:qt-example)

;; your code here

(如果您想知道,,defpackage等是专门设计的宏,可以扩展为这样的形式。)defundefclasseval-when

对于一次性的小脚本来说,这有时是可以的。对于任何值得注意的大小的系统,尤其是当它们有多个源文件时,请使用 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 带有大多数开源的 Common Lisp 实现。您可能需要设置 ASDF 注册表。我喜欢为所有本地项目创建一两个基本目录,这样我就可以将以下内容放入~/.config/common-lisp/source-registry.conf

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

然后 ASDF 会找到在这些目录下定义的所有系统。在 SLIME 中,您可以使用,load-system,open-system从带有系统名称的 REPL 来加载它,resp。打开其中的所有文件,可选择加载它。

从文件编译单个顶层表单(使用C-c C-c)时,SLIME 从那里向后in-package查找表单以找出它应该采用的包。in-package按照惯例,每个文件的顶部应该只有一个表单。

一个常用的快捷方式是C-c ~在 Lisp 源文件中,它将 REPL 切换到文件所在的目录和有效的包。

于 2014-11-23T23:13:40.287 回答