在完成Peter Seibel的书 Practical Common Lisp 时,我在理解如何与Emacs的SLIME和quicklisp一起处理Common Lisp包系统时遇到了一些困难。他提供的项目具有以下结构:
spam.lisp
中的com.gigamonkeys.spam
,它依赖于另外两个包cl-ppcre
和com.gigamonkeys.pathnames
。 pathnames.lisp
中的com.gigamonkeys.pathnames
spam.asd
,描述了com.gigamonkeys.spam
package pathnames.asd
,描述了com.gigamonkeys.pathnames
包我目前发现构建最终目标spam.lisp的唯一方法是:
pathnames.asd
)C-x C-k
文件
com.gigamonkeys.pathname
以加载(asdf:operate 'asdf:load-op 'spam)
包
cl-ppcre
以加载(ql:quickload "cl-ppcre")
包
spam.asd
文件com.gigamonkeys.spam
以加载(asdf:operate 'asdf:load-op 'spam)
包
醇>
这似乎是使用单个文件(spam.lisp
)中定义的函数所需的大量工作 - 我必须做错事。有没有办法用更少的命令加载spam.lisp
和递归地加载它的依赖项?
答案 0 :(得分:9)
长话短说,包装是符号袋和系统描述的 文件与其他系统之间的关系。
因此,在这里使用您的结构是一个简单的系统定义:
(asdf:defsystem #:spam-filter
:serial t
:description "Simple Spam Filter"
:author "PCL"
:depends-on (#:cl-ppcre
#:com.gigamonkeys.pathnames)
:components ((:file "package")
(:file "spam")))
现在,我假设系统com.gigamonkeys.pathnames
在
~/src/lisp/com/gigamonkeys/pathnames/
和垃圾邮件过滤器
~/src/lisp/spam-filter/
。
slime
RET (push (truename ".") asdf:*central-registry*)
(push (truename ".") asdf:*central-registry*)
(ql:quickload :spam-filter)
由于Quicklisp依赖ASDF加载系统,因此您需要添加系统目录 在ASDF搜索路径中。
您还可以通过添加将系统置于Quicklisp的搜索路径中
他们在~/quicklisp/local-projects/
。您可以存储代码
那里或使用符号链接。
PS:你可以找到
here
一个粘液快捷方式,允许我写,添加 RET
而不是(push (truename ".") asdf:*central-registry*)
。
就在另一个快速加载系统的粘液快捷方式下方。
(,QL some-system-name
RET )
答案 1 :(得分:3)
一点术语:
Package 是Common Lisp标准功能。包是符号的命名空间。而已。它不是文件,不是模块,不是库,并且不依赖于任何此类事物。它甚至不是函数,变量或类的命名空间。只是为了符号。有一种约定可以将设置包的定义放入自己的文件中。但这只是一个惯例。
系统用于定义,加载和编译构成软件库或应用程序的所有文件。 系统的想法已经过时(超过三十年)。 ASDF(另一个系统定义工具)是该想法的流行和免费实现。 Kent Pitman在1984年撰写了The Description of Large Systems。
此类系统工具的一部分是注册表,可以从中找到所有系统。系统定义描述了它所包含的文件以及它所依赖的所有系统。通常,这样的注册表是文件系统中的目录和/或运行Lisp中的注册表(变量,...)。
在加载特定系统时,系统工具会查看注册表并找到它,加载定义,递归加载所有需要的系统,然后加载所有文件。