【发布时间】:2011-03-23 17:44:46
【问题描述】:
我是 Lisp 的新手,正在尝试不同的方法来提高我的技能。我想编写一个包装现有函数的宏,以便我可以为这些函数设置表单之前和之后,有点像 CLOS 的辅助方法或 Elisp 的建议包。 trace 函数动态包装代码的能力引起了我的兴趣,我自己能够做到这一点似乎很有用。
我该怎么做?
请注意,我正在使用 SBCL,并且就这个问题而言,我对这样做的“正确”方式不太感兴趣,因为我正在添加到我的 Lisp 技巧包中。
【问题讨论】:
我是 Lisp 的新手,正在尝试不同的方法来提高我的技能。我想编写一个包装现有函数的宏,以便我可以为这些函数设置表单之前和之后,有点像 CLOS 的辅助方法或 Elisp 的建议包。 trace 函数动态包装代码的能力引起了我的兴趣,我自己能够做到这一点似乎很有用。
我该怎么做?
请注意,我正在使用 SBCL,并且就这个问题而言,我对这样做的“正确”方式不太感兴趣,因为我正在添加到我的 Lisp 技巧包中。
【问题讨论】:
我不知道在 CLOS 之外有任何内置支持。但是你可以重新定义原来的函数,像这样:
(defmacro add-post (fun-name &body body)
(let ((orig (gensym)))
`(let ((,orig (fdefinition ,fun-name)))
(setf (fdefinition ,fun-name) (lambda (&rest args)
(apply ,orig args)
,@body)))))
【讨论】:
(optimize debug) 生效)。
trace 指定的限制相同:“如果要跟踪的函数已被开放编码(例如,因为它被声明为内联),则调用该函数可能不会产生跟踪输出。” 但这是特殊情况,通常应在运行时查找函数定义。毕竟,这种后期绑定使 Lisp 成为一种动态语言。