我需要为(with-hooks (monster method who what) &body body)
我正在编写的游戏编写一个宏。Monster 是一个 CLOS 对象、方法和字符串,什么是函数(#' 符号)。宏观扩张的效果是
(add-hook monster method who what)
,@body
(remove-hook monster method who)
我完全不知道如何编写这样的宏,我将不胜感激。我有一种令人毛骨悚然的感觉,这很容易而且我有点无知。
我需要为(with-hooks (monster method who what) &body body)
我正在编写的游戏编写一个宏。Monster 是一个 CLOS 对象、方法和字符串,什么是函数(#' 符号)。宏观扩张的效果是
(add-hook monster method who what)
,@body
(remove-hook monster method who)
我完全不知道如何编写这样的宏,我将不胜感激。我有一种令人毛骨悚然的感觉,这很容易而且我有点无知。
我会这样写:
(defmacro with-hooks ((monster method who what) &body body)
(let ((monster-var (gensym))
(method-var (gensym))
(who-var (gensym))
(what-var (gensym)))
`(let ((,monster-var ,monster) ; dummy comment
(,method-var ,method)
(,who-var ,who)
(,what-var ,what))
(add-hook ,monster-var ,method-var ,who-var ,what-var)
(unwind-protect
(progn ,@body)
(remove-hook ,monster-var ,method-var ,who-var)))))
一些注意事项:
something-var
s 用于确保 , , , 的表达式monster
仅method
被who
计算what
一次(因为这些表达式在宏体中被多次引用)并且以从左到右的顺序进行。gensym
s 用于确保变量具有保证的唯一名称remove-hook
即使在非本地退出的情况下也会调用它(例如,由于抛出异常而导致堆栈展开)。