包通信问题Common-Lisp

Gap*_*512 2 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")))
Run Code Online (Sandbox Code Playgroud)

game.lisp与启动:

(defpackage :game
  (:use :cl :cl-ppcre))
Run Code Online (Sandbox Code Playgroud)

commands.lisp与启动:

(defpackage :commands
  (:use :cl)
  (:export "test-function"))
Run Code Online (Sandbox Code Playgroud)

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

(defun test-function ()
  (progn
    (format *query-io* "Worked!~%")
    (start)))
Run Code Online (Sandbox Code Playgroud)

test-function位于上的命令包,但调用start功能,属于game.lisp.

我打电话时,我希望调用该test-function函数(symbol-function (find-symbol "test-function" 'commands)).

sds*_*sds 5

摘要

我的主要建议是你应该有包含用户命令并包含你的Lisp代码的独立包.

不是要为你的每个Lisp的文件创建一个单独的包.

细节

你需要做的(它不是一个功能!),以确保您的代码驻留在正确的软件包,因为 仅仅创建 包,但它不会改变 .in-package defpackage*package*

因此我建议如下:

game.asd

(asdf:defsystem "game"
  :depends-on (#:cl-ppcre)
  :components ((:file "package")
               (:file "game" :depends-on ("package"))
               (:file "commands" :depends-on ("package"))))
Run Code Online (Sandbox Code Playgroud)

package.lisp

(defpackage :game
  (:use :cl :cl-ppcre))
Run Code Online (Sandbox Code Playgroud)

game.lisp

(in-package #:game)

...
Run Code Online (Sandbox Code Playgroud)

commands.lisp

(in-package #:game)

...

(defconstant *commands-package* (make-package '#:commands :use nil))
Run Code Online (Sandbox Code Playgroud)

然后使用intern添加命令*commands-package*find-symbol查找它们.

(defun test-command ()
  (format t "test-command~%")
  (start))
(intern 'test-command *commands-package*)
Run Code Online (Sandbox Code Playgroud)

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

(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))
Run Code Online (Sandbox Code Playgroud)

吹毛求疵