如何编写(简单)宏?

发布于 2024-09-02 05:55:12 字数 320 浏览 4 评论 0原文

我需要为我正在编写的游戏编写一个宏 (with-hooks (monster method who what) &body body) 。 Monster 是一个 CLOS 对象,方法,谁是字符串,什么是函数(#' 符号)。宏扩展的效果是

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

绝对不知道如何编写这样的宏,并且我将不胜感激。 我有一种毛骨悚然的感觉,这很容易,而且我有点无知。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陪我终i 2024-09-09 05:55:12

我会这样写:

(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用于确保monstermethod的表达式whowhat 仅按从左到右的顺序计算一次(因为这些表达式在宏体中被多次引用)。
  2. gensym 用于确保变量具有唯一的名称
  3. unwind-protect 用于确保即使在非本地退出的情况下也会调用 remove-hook (例如,由于抛出异常而堆栈展开)。

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:

  1. something-vars 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.
  2. gensyms are used to ensure that variables have guaranteed unique names
  3. 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).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文