2010-05-23 7 views
5

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

(add-hook monster method who what) 
,@body 
(remove-hook monster method who) 

У меня абсолютно не знаю, как написать такой макрос, и я был бы признателен за помощь. У меня жуткое чувство, что это легко, и я немного невежественен.

ответ

10

Я бы написал так:

(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-var s используются для того, чтобы выражения для monster, method, who, what вычисляются только один раз (из-за эти выражения ссылаются несколько раз в макрообъекте) и в порядке слева направо.
  2. gensym s используются для обеспечения того, чтобы переменные гарантированно уникальные имена
  3. размотки-защиты используется для того, чтобы remove-hook называется даже в случае нелокальных выходов (например, стек раскручивать из-за исключением броска).
+2

смешной, я написал тот же код почти по очереди –

+0

Спасибо. Я работаю над игрой GPL roguelike под названием Menace of the Mines (http://motm.sourceforge.net) и просто хочу убедиться, что это происходит с вами. (У меня есть объяснительный комментарий (он был там некоторое время)) – krzysz00

+0

Я не против, если вы включите этот макрос в какой-либо проект в любом случае. –

Смежные вопросы