程序包通信Common-Lisp问题

时间:2019-01-16 15:41:01

标签: lisp common-lisp

我定义了两个软件包:game(文件game.lisp)和commands(文件commands.lisp),由一个game.asd文件加载。我在使用(symbol-function (find-symbol "test-function" 'commands))调用命令功能(已导出的功能)时遇到了麻烦,即使(find-symbol "test-function" 'commands)返回的功能是外部的,并且属于该功能,该功能仍未定义commands包。

game.asd文件上的代码是:

(asdf:defsystem "game"
  :depends-on (#:cl-ppcre)
  :components ((:file "game")
               (:file "commands")))

game.lisp的开头为:

(defpackage :game
  (:use :cl :cl-ppcre))

commands.lisp的开头为:

(defpackage :commands
  (:use :cl)
  (:export "test-function"))

我需要使用in-package函数吗? 我从game.lisp调用存储在commands.lisp文件中的命令,其中一些调用game.lisp上的某些函数,例如:

(defun test-function ()
  (progn
    (format *query-io* "Worked!~%")
    (start)))

test-function位于命令包中,但调用start所属的game.lisp函数。

我期望在调用test-function时调用(symbol-function (find-symbol "test-function" 'commands))函数。

2 个答案:

答案 0 :(得分:5)

摘要

我的主要建议是,您应该具有包含用户命令和Lisp代码的单独软件包。

不必必须为每个Lisp文件创建一个单独的程序包。

详细信息

您确实需要in-package (不是 function !),以确保您的代码位于 正确的包装,因为 defpackage只是创建 包,它不会更改 *package*

因此,我建议以下内容:

文件

game.asd

(asdf:defsystem "game"
  :depends-on (#:cl-ppcre)
  :components ((:file "package")
               (:file "game" :depends-on ("package"))
               (:file "commands" :depends-on ("package"))))

package.lisp

(defpackage :game
  (:use :cl :cl-ppcre))

game.lisp

(in-package #:game)

...

commands.lisp

(in-package #:game)

...

(defconstant *commands-package* (make-package '#:commands :use nil))

,然后使用intern添加 *commands-package*find-symbol的命令来查找它们。

(defun test-command ()
  (format t "test-command~%")
  (start))
(intern 'test-command *commands-package*)

您还可以为此定义自己的宏:

(defmacro defcommand (name arglist &body body)
  `(progn
     (intern (symbol-name ',name) *commands-package*)
     (defun ,name ,arglist ,@body)))

(defcommand test-command ()
  (format t "test-command~%")
  (start))

山雀

答案 1 :(得分:0)

我不确定您为什么要做find-symbol的事情。如果只想调用另一个包中定义的函数,则有两个选择:

  • 如评论中所述,您可以use其他包裹:
    (defpackage :game 
      (:use :cl 
            :cl-ppcre 
            :commands))
    (in-package :game)
  • 或使用(commands:test-function)调用该函数(如果未导出该函数,则使用双冒号::)。

以下是新项目的示例定义:https://lispcookbook.github.io/cl-cookbook/getting-started.html#creating-a-new-project

另请参阅处理软件包的提示:https://lispcookbook.github.io/cl-cookbook/packages.html