【问题标题】:How to dynamically wrap existing functions, such as for a profiler?如何动态包装现有功能,例如探查器?
【发布时间】:2011-03-23 17:44:46
【问题描述】:

我是 Lisp 的新手,正在尝试不同的方法来提高我的技能。我想编写一个包装现有函数的宏,以便我可以为这些函数设置表单之前和之后,有点像 CLOS 的辅助方法或 Elisp 的建议包。 trace 函数动态包装代码的能力引起了我的兴趣,我自己能够做到这一点似乎很有用。

我该怎么做?

请注意,我正在使用 SBCL,并且就这个问题而言,我对这样做的“正确”方式不太感兴趣,因为我正在添加到我的 Lisp 技巧包中。

【问题讨论】:

    标签: function macros lisp sbcl


    【解决方案1】:

    我不知道在 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)))))
    

    【讨论】:

    • 问题:Common Lisp 是否允许实现编译引用被调用函数的编译时 fdefinition 的函数,而不是让它在运行时查找 fdefinition?如果是这样,那么换出 fdefinition 不一定会起作用(大概除非(optimize debug) 生效)。
    • 我认为与 CLHS 中为 trace 指定的限制相同:“如果要跟踪的函数已被开放编码(例如,因为它被声明为内联),则调用该函数可能不会产生跟踪输出。” 但这是特殊情况,通常应在运行时查找函数定义。毕竟,这种后期绑定使 Lisp 成为一种动态语言。
    • 这很好,即使作为一个函数。但是,我不得不在代码中的每个位置使用 ',fun-name 而不是 ,fun-name。
    • @gamecoder: 是的,我假设宏的用户会引用函数名,但是通过在宏定义中引用你就没有必要了。
    猜你喜欢
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 2019-05-09
    • 2013-04-10
    • 2021-06-11
    相关资源
    最近更新 更多