通用Lisp中的包通信问题

通用Lisp中的包通信问题,lisp,common-lisp,Lisp,Common Lisp,我定义了两个包:game(文件game.lisp)和commands(文件commands.lisp),由game.asd文件加载。使用(symbol function(find symbol“test function”commands))调用命令函数(已导出)时遇到问题,它返回函数未定义,即使(find symbol“test function”commands)返回函数是外部的,并且属于命令包 game.asd文件上的代码是: (asdf:defsystem "game" :depen

我定义了两个包:
game
(文件
game.lisp
)和
commands
(文件
commands.lisp
),由
game.asd
文件加载。使用
(symbol function(find symbol“test function”commands))
调用命令函数(已导出)时遇到问题,它返回函数未定义,即使
(find symbol“test function”commands)
返回函数是外部的,并且属于
命令

game.asd
文件上的代码是:

(asdf:defsystem "game"
  :depends-on (#:cl-ppcre)
  :components ((:file "game")
               (:file "commands")))
game.lisp
以以下内容开头:

(defpackage :game
  (:use :cl :cl-ppcre))
(defpackage :commands
  (:use :cl)
  (:export "test-function"))
commands.lisp
以以下内容开头:

(defpackage :game
  (:use :cl :cl-ppcre))
(defpackage :commands
  (:use :cl)
  (:export "test-function"))
我是否需要使用软件包中的
功能?
在
game.lisp
中,我调用存储在
commands.lisp
文件中的命令,其中一些调用
game.lisp
上的一些函数,例如:

(defun test-function ()
  (progn
    (format *query-io* "Worked!~%")
    (start)))
test函数
位于commands包中,但调用
start
函数,该函数属于
game.lisp

当我调用
(symbol函数(查找symbol“test function”命令))时,我希望调用
测试函数
函数

摘要 我的主要建议是,您应该有单独的包,其中包含用户命令和Lisp代码

您不必为每个Lisp文件创建单独的包

细节 你确实需要 宏(它不是函数!),以确保代码驻留在 正确的包装,因为 仅仅创造 包,它不会改变

因此,我建议如下:

文件夹
game.asd
package.lisp
game.lisp
commands.lisp
然后使用添加 命令到
*命令包*
并查找它们

(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))
挑剔
  • 不要将函数体包装在显式 ,因为 这是为你做的

  • 找到一个 ,而不是

  • 别忘了把论点讲清楚


    • 我不知道你为什么要做
      查找符号
      之类的事情。如果您只想调用另一个包中定义的函数,则有两个选项:

      • 如评论中所述,您可以
        使用另一个软件包:
      • 或者使用
        (命令:测试函数)
        (如果函数未导出,则使用双冒号
        )调用函数
      以下是新项目的示例定义:


      另请参见处理软件包的提示:

      您可以
      :使用…:命令
      package in
      :game
      将导出的函数设置为“本地”:
      (defpackage:game(:use:cl:cl-ppcre:commands))
      。我在game.asd上切换了初始化顺序(否则,系统返回找不到命令包)并将
      命令
      包添加到
      游戏
      包定义的
      使用
      ,但错误仍然出现(函数未定义)默认情况下,符号在Common Lisp中为大写。使用“TEST-FUNCTION”作为符号名字符串。关于宏,在尝试加载和编译
      命令时,会出现错误
      绑定SB-IMPL::name时,值TEST-COMMAND不是字符串类型。lisp
      。为了确保这一点,我需要在REPL中加载并编译game.asd文件,调用
      (asdf:load system'game)
      并将包更改为
      :game
      ?非常感谢您的帮助。无论您是在CL-USER软件包中还是在游戏软件包中与您的代码交互,这都只是个人方便的问题。Uiop(ASDF的一部分)具有
      Uiop:standard case symbol name
      ,它至少还支持Allegro的“现代”模式。感谢您的回答和提供的资料,但这样做是行不通的。在这个问题中,我解释了为什么我需要
      查找符号
      (从用户输入调用函数,从字符串转换而来)。
      (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))
      
          (defpackage :game 
            (:use :cl 
                  :cl-ppcre 
                  :commands))
          (in-package :game)