【发布时间】:2020-03-24 09:57:57
【问题描述】:
我对 Common Lisp 宏还是很陌生。
对于具有 defgeneric 的 defclass 的抽象,我认为制作一个宏会很好。
一个非常幼稚的实现看起来像:
(defmacro defgserver (name &key call-handler cast-handler)
"TODO: needs firther testing. Convenience macro to more easily create a new `gserver' class."
`(progn
(defclass ,name (gserver) ())
(defmethod handle-call ((server ,name) message current-state)
,(if call-handler call-handler nil))
(defmethod handle-cast ((server ,name) message current-state)
,(if cast-handler cast-handler nil))))
使用时,错误提示“消息”未知。
我不知道。 'message' 是defgeneric 的参数名称:
(defgeneric handle-call (gserver message current-state))
使用宏我看到警告“未定义的变量消息”:
(defgserver foo :call-handler
(progn
(print message)))
; in: DEFGSERVER FOO
; (PRINT MESSAGE)
;
; caught WARNING:
; undefined variable: COMMON-LISP-USER::MESSAGE
使用时会产生这样的后果:
CL-USER> (defvar *my* (make-instance 'foo))
*MY*
CL-USER> (call *my* "Foo")
<WARN> [10:55:10] cl-gserver gserver.lisp (handle-message fun5) -
Error condition was raised on message processing: CL-GSERVER::C: #<UNBOUND-VARIABLE MESSAGE {1002E24553}>
所以message 和/或current-state 一定会发生一些事情。
是否应该将它们实习到使用宏的当前包中?
曼弗雷德
【问题讨论】:
-
结帐
macroexpand-1看看你用你的宏生成什么样的代码... -
通常看起来这是一个包问题。宏中的
message必须与defgserver表单中的message符号相同。 -
macroexpand 在我看来没问题。当在定义
defgeneric的包内使用时,它可以工作。但不是其他地方。
标签: common-lisp