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 for monster
, 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 namesremove-hook
is called even in case of non-local exits (e.g., stack unwind due to exception being thrown).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With