【问题标题】:How to load external dependencies with quicklisp?如何使用 quicklisp 加载外部依赖项?
【发布时间】:2013-09-15 10:32:02
【问题描述】:

这是我的代码:

(defpackage :com.yves.tests (:use :common-lisp))
(in-package :com.yves.tests)
(require :usocket)

每次我评估 require 指令时,我都会收到此错误:

LOAD: A file with name #1=USOCKET does not exist
   [Condition of type SYSTEM::SIMPLE-FILE-ERROR]

当然,我在我的 REPL 中安装了带有 quickload 的包:

CL-USER> (ql:quickload "usocket")
To load "usocket":
  Load 1 ASDF system:
    usocket
; Loading "usocket"

("usocket")
CL-USER> 

实际上,我昨天晚上已经安装了它,我的所有代码都在评估,没有任何抱怨。今天我重新启动了 Emacs 和 Slime。我得到这个错误。是否需要额外配置?

这是我的加载路径中的内容:

CL-USER> (princ custom:*load-paths*)
(/Users/yves/quicklisp/ /opt/local/lib/clisp-2.49/dynmod/ ./ ~/lisp/**/)
(#P"/Users/yves/quicklisp/" #P"/opt/local/lib/clisp-2.49/dynmod/" #P"./"
 "~/lisp/**/")
CL-USER> 

我应该手动添加每个新包的路径吗? quicklisp 初始化不应该自己执行吗?

【问题讨论】:

    标签: emacs lisp common-lisp clisp quicklisp


    【解决方案1】:

    Svante 已经回答了您的问题的基本解决方案,但是将 quicklisp 与 asdf(和 .asd 文件)结合使用可能会更舒服,以便能够更轻松地扩展项目及其要求。

    .asd 文件的设置可能如下所示:

    ;;foobar.asd
    (asdf:defsystem :foobar ;this is the name of your project
       :depends-on (:usocket) ;those are the names of the dependencies
       :components ((:file "the-file-name"))) ;this .asd has to be in the same folder (asdf-keyword :module)
    

    定义您的 foobar.asd 后,您要么将项目移动到 .quicklisp/local-project/(符号链接即可)文件夹中,要么告诉 asdf how to find your project

    现在你应该可以通过(ql:quickload :foobar)加载你的项目了

    从现在开始,asdf/quicklisp 将在加载您的项目之前负责(下载)所有已定义的依赖项。

    如果您以后想要扩展您的项目并因此扩展您的项目 .asd 文件,您可以在 asdf manualstackoverflow 找到有价值的信息。 asdf的项目页面可以访问here

    【讨论】:

      【解决方案2】:

      Require 不是这里需要的操作。

      在您将整个系统放在一个自给自足文件中的简单情况下,您可以将ql:quickload 表单包装成eval-when

      (in-package #:cl-user)
      
      (eval-when (:compile-toplevel :load-toplevel :execute)
        (ql:quickload "usocket"))
      
      (defpackage #:com.yves.tests
        (:use #:cl))
      
      (in-package #:com.yves.tests)
      
      ;; your code here
      

      如果你想使用 usocket 中的符号而不加限定,请在 defpackage 形式中使用:

      (defpackage #:com.yves.tests
        (:use #:cl #:usocket))
      

      如果您有一个跨越多个文件的更大系统,您可以使用 ASDF。运行简单设置的快速方法是 quickproject,也可从 Quicklisp 获得。

      【讨论】:

      • 非常棒,因为您的第一个提议正在奏效。昨天我用的是第二个。今天早上启动 Emacs 后,它正在打印我的问题中显示的错误。我稍微摆弄了一下,将它从:use 指令中删除,并用require 替换它。我想我需要更深入地了解 lisp 的命名空间理解。再次感谢。
      • 谁能解释一下#:packagename和简单的:packagename有什么区别?我看到了两个版本,但不知道有什么区别。
      • @dptd: Defpackage 在大多数地方都采用 字符串指示符(参见 CLHS 中的词汇表)。任何符号也是其名称的字符串指示符。在读取时,symbol 获取或创建(有效地)一个嵌入到当前包中的符号,:symbol 获取或创建一个嵌入到 KEYWORD 包中的符号,而#:symbol 总是创建一个新的未嵌入符号。通过使用最后一种形式,当您只关心名称时,您可以避免所有不必要的实习。这是一个很小的优化,所以有些人甚至在这里只使用普通符号,因为这在源文件中看起来更干净。
      猜你喜欢
      • 2017-12-05
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多