【问题标题】:Common lisp — why isn't this symbol external?Common lisp——为什么这个符号不是外部的?
【发布时间】:2020-05-15 14:23:15
【问题描述】:

我正在尝试在 ASDF 中运行测试,如下所示:

;;;; foo.asd

(defsystem "foo/tests"
  :depends-on ("foo"
               "fiveam")
  :components ((:module "tests"
                :components
                ((:file "main"))))
  :perform (test-op (op c) (symbol-call :fiveam '#:run! 'foo/tests:all-tests))

我的tests/main.lisp 文件是这样开始的:

;;;; tests/main.lisp

(defpackage foo/tests
  (:use :cl
        :foo
        :fiveam)
  (:export :#run! :#all-tests))
(in-package :foo/tests)

当我在 REPL 中运行 (asdf:test-system 'foo) 时,我会使用 LOAD-SYSTEM-DEFINITION-ERROR 进入调试器。调试器抱怨The symbol "ALL-TESTS" is not external in the FOO/TESTS package.

但是,我显然是在 foo/tests 包中导出符号。有人可以告诉我我在这里缺少什么以及为什么 Lisp 编译器没有看到外部符号吗?非常感谢。

【问题讨论】:

  • foo.asd 在main.lisp 加载之前被读取,所以defpackage 还没有被执行。
  • @Barmar:这就是symbol-call 表单解决的问题。
  • @svante: foo/tests:all-tests 是尚未定义 (?) 包中的外部符号。 symbol-call 如何解决这个问题,它不是在读取时执行的?在读取 DEFSYSTEM 表单之前,他需要以某种方式获得该软件包?
  • @RainerJoswig:对不起,你们都说得对,我只是看了一眼表格。正如所写,它只解决了fiveam:run! 的问题,而不是论点。
  • 早就有人说,选择在 CLTL 的第 11 章中描述包是经过深思熟虑的。

标签: package common-lisp asdf


【解决方案1】:

uninterned 符号的语法是#:foo,而不是:#foo。

您还需要在运行时解析:perform 表单中的符号,例如。 G。通过uiop:find-symbol*,就像你在那里使用uiop:symbol-call一样。

:perform (test-op (op c)
           (symbol-call :fiveam '#:run!
                        (find-symbol* '#:all-tests '#:foo/tests)))

或者,由于您似乎从测试包中导出了 run! 函数,您可能想要调用它而不是 fiveam:run!:

:perform (test-op (op c)
           (symbol-call '#:foo/tests '#:run!))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    • 2011-12-15
    • 2019-01-18
    • 2011-04-20
    • 2021-10-04
    • 2021-08-06
    • 1970-01-01
    相关资源
    最近更新 更多