【问题标题】:clojure: adding a debug trace to every function in a namespace?clojure:为命名空间中的每个函数添加调试跟踪?
【发布时间】:2010-07-27 17:50:36
【问题描述】:

刚开始在我的一个家庭项目中使用 log4j,我正准备用鼠标将 (trace (str "entering: " function-name)) 剪切并粘贴到一个大模块中的每个函数中。然后理性的声音出现并说“必须有更好的方法”......我可以想到制作一个包含整个函数块并将跟踪添加到它们的宏或类似的东西?明智的 Stack-overflowing-clojurians 有什么建议吗?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    不需要宏:

    (defn trace-ns
      "ns should be a namespace object or a symbol."
      [ns]
      (doseq [s (keys (ns-interns ns))
              :let [v (ns-resolve ns s)]
              :when (and (ifn? @v) (-> v meta :macro not))]
        (intern ns
                (with-meta s {:traced true :untraced @v})
                (let [f @v] (fn [& args]
                              (clojure.contrib.trace/trace (str "entering: " s))
                              (apply f args))))))
    
    (defn untrace-ns [ns]
      (doseq [s (keys (ns-interns ns))
              :let [v (ns-resolve ns s)]
              :when (:traced (meta v))]
        (alter-meta! (intern ns s (:untraced (meta v)))
                     #(dissoc % :traced :untraced))))
    

    ...或类似的东西。最可能的额外要求是使用filter,以免在不是ifn?s 的事情上调用trace更新:在解决方案中进行了编辑(也处理宏)。更新 2:修复了一些主要错误。更新 4:添加了 untrace 功能。

    更新 3: 这是我的 REPL 中的一个示例:

    user> (ns foo)
    nil
    foo> (defn foo [x] x)
    #'foo/foo
    foo> (defmacro bar [x] x)
    #'foo/bar
    foo> (ns user)
    nil
    user> (trace-ns 'foo)
    nil
    user> (foo/foo :foo)
    TRACE: "entering: foo"
    :foo
    user> (foo/bar :foo)
    :foo
    user> (untrace-ns 'foo)
    nil
    user> (foo/foo :foo)
    :foo
    

    【讨论】:

    • 你简直太棒了!你能解释一下 ns-resolve 部分吗?
    • :-) ns-resolve 接受一个命名空间或命名空间命名符号和一个符号,并尝试在(第二个)符号给出的名称下找到一个实习在给定命名空间中的 Var。这里的重点是 (1) 可以更改 Var 的根绑定(有很多方法可以做到,但 intern 在这里特别方便,因为它还处理额外的元数据;trace-ns 使用重新绑定用包装函数代替原始函数)和(2)可以更改 Var 的元数据(所以 untraced-ns 是可能的)。
    • 请参阅gist.github.com/492764 以获取上述最新版本(具有更有用的文档字符串!)。
    • 现在是tools.trace Contrib 库的一部分,形式略有修改。 (其实去年 2 月就已经合并了,不过我现在才想起来在这里加个评论。)
    猜你喜欢
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多