Я должен записать макрос (with-hooks (monster method who what) &body body)
для игры я пишу. Монстр является объектом 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
, метод
, who
, what
оцениваются только один раз (поскольку на эти выражения ссылаются несколько раз в теле макроса) и в порядке слева направо. gensym
используются для того, чтобы гарантировать, что переменные имеют гарантированные уникальные имена. remove-hook
вызывается даже в случае нелокальных выходов (например, , раскрутка стека из-за возникшего исключения).