How to write (simple) macro?
I need to write a macro (with-hooks (monster method who what) &body body)
开发者_开发技巧for a game I'm writing. Monster is a CLOS object, method and who are strings and what is a function (#' notation). The macroexpansion would be something to the effect of
(add-hook monster method who what)
,@body
(remove-hook monster method who)
I have absolutely no idea how to write such a macro, and I would appreciate some help. I have the creepy feeling that this is easy and I'm a bit ignorant.
I'd write it like this:
(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)))))
Some notes:
something-var
s are used to ensure that expressions formonster
,method
,who
,what
are evaluated only once (because these expressions are referenced multiple times in macro body) and in left-to-right order.gensym
s are used to ensure that variables have guaranteed unique names- unwind-protect is used to ensure that
remove-hook
is called even in case of non-local exits (e.g., stack unwind due to exception being thrown).
精彩评论