【问题标题】:Using Swank functions in a library在库中使用 Swank 函数
【发布时间】:2013-10-27 04:09:19
【问题描述】:

我在 Ubuntu Raring 上使用 SLIME/SBCL/Emacs 和 Quicklisp。我有下面定义的功能。我想添加到我的 Lisp 库的顶级 .lisp 文件中,即每隔一个依赖的文件,这样我就可以在我用我的库编写的所有函数中使用它,只需将 (update-swank) 添加到函数而不是必须将下面的整个函数添加到使用它的每段代码中。

(defun update-swank ()
   "Grabs SWANK connections and tells it to handle requests. 
    Call this every loop in the main loop of your program"
   (continuable
     (let ((connection (or swank::*emacs-connection*
               (swank::default-connection))))
       (when connection
     (swank::handle-requests connection t)))))

当我这样做并重新启动 emacs 时,因为我的 .sbclrc 文件中有 asdf:load-op,所以在此过程中加载我的库,我得到一个

READ error during COMPILE-FILE:
;   
   ;     Package SWANK does not exist.

在劣质 lisp 中,SLIME 卡住轮询,因为库没有加载,因为在我当前的设置中,SLIME/SBCL 在加载 update-swank 所在的 .lisp 文件时不知道 swank 是什么。我尝试将(in-package :swank) 添加到update-swank 所在的文件中,但得到了

The name "SWANK" does not designate any package.

当我的库在 emacs 启动时加载时,在劣质 lisp 中。

我搜索了 CEPL(我从 https://github.com/cbaggers/cepl/blob/master/cepl-utils.lisp 获得了 update-swank),然后复制了 CEPL 的创建者所做的并将该函数导出到我的 packages.lisp 中。我确保添加了函数,就像他在 cepl-utils 的第 20 行所做的那样 https://github.com/cbaggers/cepl/blob/master/cepl-utils.lisp......I 顺便加载我的库

(asdf:operate 'asdf:load-op :cl-test)
(in-package #:cl-test)

在我的 .sbclrc 文件中,我假设它是在我的 .emacs 文件在 emacs 启动时加载粘液之前加载的(我的 .emacs 文件中有 (slime))...我刚刚测试了删除 adsf:load-opin-package 和我的 .sbclrc 并在加载了 slime/swank 之后运行 asdf:load-op 并且我在这里一直在尝试做的事情没有错误......但我希望能够加载我的库在emacs启动时自动加载,我通常这样做的方式是将asdf:load-op添加到我的.sbclrc....如果有人能告诉我在加载swank后在emacs启动时自动加载我的库的另一种方法,那将回答这个?

【问题讨论】:

  • 为什么不把它变成一个真正的库,把它放在 Quicklisp 存储其他本地项目的地方呢?你可以在启动 Lisp 后随时asdf:load-opql:quickload

标签: common-lisp slime swank


【解决方案1】:

如果在运行的 Lisp 中没有定义包,则不能使用该包。首先,您需要定义包,然后您可以从该包中读取符号。当 CL 尝试从未知包中读取符号时,不会创建包。

如果(find-package "FOO") 返回 NIL,则您无法读取像 FOO::BAR 这样的符号。

两个解决方案是:

  • 在读取包中的符号之前执行包定义

  • 从源代码中删除符号:

例子:

foo::*bar*

替换为

(symbol-value (find-symbol "*BAR*" "FOO"))

上面在运行时找到符号并检索符号值。

还有:

(foo::bar :baz t)

替换为

(funcall (symbol-function (find-symbol "BAR" "FOO")) :baz t)

上面在运行时找到符号,检索函数并调用它。

【讨论】:

    【解决方案2】:

    这是在游戏/实时演示的主循环中设置的,因为这是阻止 repl 更新的原因。幸运的是,我们控制了循环,所以这很容易。现在您想在您的库中使用它(可能与 opencv 一起使用),因此您需要确定是什么阻止了更新,如果您可以访问主循环,这通常是某种“主循环”,然后调用 update-swank在那里。

    如果主循环由外部库控制,那么也许您可以将其放在一个函数中,该函数在每个“循环”中都被调用。您真正需要的只是调用足够频繁,以使 repl 感觉响应。

    除此之外,您可以尝试将 swank 的设置更改为在单独的线程上运行,尽管我没有这样做的经验,所以我无法告诉您效果如何。

    您可以在 (run-demo) function of this example 的主循环中看到它

    我也谈论它in this video。虽然可能不够详细:)

    你得到“swank 不存在”的事实很奇怪。提示 swank 没有加载,但如果你使用的是 slime,那么 swank 必须在那里!

    附言请记住,这是与 Slime 或 Slim 一起使用的,这意味着您将它们与 emacs 或 vim 一起使用。如果您不使用 Slime+emacs 或 Slim+vim,此功能将不起作用

    [编辑] 好的,所以我通过将 (ql:quickload :cepl) 放在 quicklisp 的 setup.lisp 文件的末尾来复制您的问题。这给了我“包 SWANK 不存在”。解决此问题的一种快速方法是在项目的 asd 文件中将 swank 指定为依赖项。比如:

    (asdf:defsystem #:cepl
      :serial t
      :depends-on (#:cl-opengl
                   #:swank     ;;<---HERE
                   #:lbm-sdl
                   #:varjo
                   #:cl-utilities
                   #:cl-ppcre
                   #:symbol-munger
                   #:classimp
                   #:temporary-file
                   #:md5)
      :components ((:file "package")
                   (:file "maths/base-maths")
                   (:file "base-macros")
                   ;; (:file "base-lispbuilder")
                   (:file "cepl-utils")
    

    希望对你有帮助:)

    【讨论】:

    • 我刚刚编辑了我的问题以更清楚......我认为我以前的模糊性?导致你误解了我想要完成的事情
    • 好的我明白了,我去看看
    • 是的,我要从我的答案中删除该行。
    • 为了完整起见也删除了我的@Baggers
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 2017-06-17
    • 2014-09-18
    相关资源
    最近更新 更多