clojure: adding a debug trace to every function in a namespace?

后端 未结 1 496
自闭症患者
自闭症患者 2020-12-13 20:40

just started using log4j in one of my home-projects and I was just about to break out the mouse and cut-and-paste (trace (str \"entering: \" function-name)) in

相关标签:
1条回答
  • 2020-12-13 21:15

    No need for a macro:

    (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))))
    

    ...or something similar. The most likely extra requirement would be to use filter so as not to call trace on things which aren't ifn?s. Update: edited in a solution to that (also handling macros). Update 2: fixed some major bugs. Update 4: added untrace functionality.

    Update 3: Here's an example from my 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
    
    0 讨论(0)
提交回复
热议问题