在Debian上用Common Lisp和SLIME加载外部包
我在Debian挤压上使用SBCL 1.0.56,使用cl swank/slime 1:20120420-2(Debian版本号)。这些都是当前的趋势 版本不稳定 我在加载第三方CL包时遇到问题。这个 在Debian上使用CL的文档(实际上是更通用的CL Linux上的使用说明文件)是粗略的、矛盾的,而且 过时了,所以我会总结一下我所知道的。这就是我所处的位置 Debian在中安装二进制软件包(例如cl split sequence)在Debian上用Common Lisp和SLIME加载外部包,debian,common-lisp,packages,slime,sbcl,Debian,Common Lisp,Packages,Slime,Sbcl,我在Debian挤压上使用SBCL 1.0.56,使用cl swank/slime 1:20120420-2(Debian版本号)。这些都是当前的趋势 版本不稳定 我在加载第三方CL包时遇到问题。这个 在Debian上使用CL的文档(实际上是更通用的CL Linux上的使用说明文件)是粗略的、矛盾的,而且 过时了,所以我会总结一下我所知道的。这就是我所处的位置 Debian在中安装二进制软件包(例如cl split sequence) /usr/share/common lisp/source。
/usr/share/common lisp/source
。在拆分序列的情况下,这是
/usr/share/common lisp/source/cl拆分序列
.asd文件(此处为
/usr/share/common lisp/source/cl split sequence/split sequence.asd
),
据我所知,它为CL的实现提供了指导
关于版本和依赖项,如下所示
;;; -*- Lisp -*- mode
(defpackage #:split-sequence-system (:use #:cl #:asdf))
(in-package :split-sequence-system)
(defsystem :split-sequence
:version "20011114.1"
:components ((:file "split-sequence")))
现在,在运行slime时,在REPL处输入以下两行
工作没有问题
(require :split-sequence)
(split-sequence:SPLIT-SEQUENCE #\, "foo,bar")
(require:splitsequence)
调用(我认为)的内置副本
SBCL中的ASDF,它可能查看分割序列.asd
。这
可能是SBCL特定的,请参阅。
值得注意的是,这一页,这是有用的和详细的
我遇到的任何事情,都经常提到CLC(通用
Lisp控制器),但Debian似乎正在远离这一点。看见
,
我不完全理解。无论如何,没有任何一项记录在案
使用CLC的命令对我有用。但是,CLC仍然可用
关于Debian。此外,用户邮件列表已失效-请参阅
第一次调用(require:split sequence)
时,将对其进行编译,
并且(在我的系统上,可能是特定于Debian的)生成的fasl
是
置于
~/.cache/common lisp/sbcl-1.0.56.0.debian-linux-x86/usr/share/common lisp/source/cl split sequence/split sequence.fasl
也就是说,文件被放置在镜像
原始源的位置。一个显而易见的问题是,这个问题如何解决
系统知道在哪里寻找包裹吗?这是我不喜欢的一件事
当然可以。看起来应该在中给出搜索路径
/etc/common lisp/source registry.conf.d
,它是ASDF的一部分
Debian包,但最接近的是
01 common lisp controller.conf
,它只是
(:directory #p"/usr/share/common-lisp/systems/")
也许这是硬接线的地方,但我想知道
无论如何,一旦这个ASDF文件进入缓存,它就不会被再次编译,
但是,除非有人看到,否则REPL在黏液启动后不会看到它
再次要求
现在,如果我把线
(require :split-sequence)
(split-sequence:SPLIT-SEQUENCE #\, "foo,bar")
在一个文件中,比如说seq.lisp
,然后用C-C-k将它加载到REPL中,我得到
错误和回溯,从
The name "SPLIT-SEQUENCE" does not designate any package.
[Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]
因此,我的结论是,包没有正确加载。我试过这样的变化
(asdf:oos 'asdf:load-op :split-sequence)
及
但是没有骰子。奇怪的是,假设我们只有这条线
(require :split-sequence)
在文件中-为清晰起见,请调用此require.lisp
。然后加载
require.lisp
没有给出错误,然后键入
(split-sequence:SPLIT-SEQUENCE #\, "foo,bar")
在REPL工厂!但是,在不加载require.lisp
的情况下,键入
前一行在REPL处不起作用
因此,总而言之,如何才能成功地将包加载到
剧本我也会对上面提到的问题感兴趣,关于
ASDF是如何找到/usr/share/common lisp/source/
位置的,但是
这更多的是一个枝节问题。我看到了下面的帖子,上面有链接到 复制该文件顶部的代码是有效的。因此,在此文件上运行slime中的C-C-k将加载
split sequence
,并运行codeint(split sequence:split-sequence\35;\,“foo,bar”)
然而,我不知道这些神奇的咒语是做什么的。有没有人愿意解释一下,也许是另一个答案?我把它放在一个答案中,因为它是对这个问题的回答,但它并不完整,因为我不明白它为什么有效。我很乐意接受这个脚本的解释。C-C-k编译源文件,然后加载编译后的文件
Lisp源文件包含定义和调用。文件编译器遍历文件并为其创建代码。但它并没有执行它
如果文件包含对REQUIRE
的调用,则编译期间不会执行该调用。如果以后加载编译后的文件,将执行该命令。如果文件中的下一个Lisp表单使用的是调用REQUIRE
后可用的某个包,那么它在编译过程中就不存在了,因为REQUIRE
尚未执行,因此在编译过程中读取时会出现错误
基本上有两种解决方案:
- 在使用所需功能编译特定文件之前,请执行所有必要的
操作REQUIRE
- 在编译期间执行
语句。这就是REQUIRE
告诉编译器在编译期间执行子表单的地方EVAL-WHEN:COMPILE-TOPLEVEL
#+:sbcl(foo)
表示当:sbcl
是列表中的符号时(foo)是只读的CL:*功能*
。它的使用使得编译器仅在使用SBCL时才能看到此代码
公共Lisp代码的编译需要更仔细地准备,因为:
- 可以在文件编译期间执行Lisp代码,从而更改文件编译器的行为
- 文件编译器的读者需要知道源代码中使用的包(符号的名称空间)
#+:sbcl
能做什么?回答我自己的问题-显然不多。只需(在(:编译顶级:加载顶级:执行)时求值(要求:拆分序列))(打印(拆分)
(split-sequence:SPLIT-SEQUENCE #\, "foo,bar")
#+:sbcl
(eval-when (:compile-toplevel :load-toplevel :execute)
(require :asdf))
(eval-when (:compile-toplevel :load-toplevel :execute)
(asdf:oos 'asdf:load-op :split-sequence))
(defpackage #:seq
(:use #:cl #:split-sequence))
(in-package #:seq)
(print (split-sequence:SPLIT-SEQUENCE #\, "foo,bar"))