Вопрос

Мне нужно написать макрос (with-hooks (monster method who what) &body body) Для игры я пишу. Monster - это закрытый объект, метод и кто являются строками, и что такое функция (# «нотация). Macroexpansion будет чем-то для эффекта

(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)))))

Некоторые заметки:

  1. something-vars используются для обеспечения того, чтобы выражения для monster, method, who, what оцениваются только один раз (потому что эти выражения ссылаются несколько времен в корпусе макроса) и в порядке лево-правильного.
  2. gensymS используются для обеспечения того, чтобы переменные были гарантированы уникальные имена
  3. Отдожди защита используется для обеспечения того, чтобы remove-hook называется даже в случае не локальных выходов (например, стека, расслабиться из-за брошенного исключения).
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top