Skip to content

Instantly share code, notes, and snippets.

@michalmarczyk
Created February 17, 2012 00:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michalmarczyk/1849273 to your computer and use it in GitHub Desktop.
Save michalmarczyk/1849273 to your computer and use it in GitHub Desktop.
Mass tracing utilities for Clojure
;;; See the inspirational SO question: http://stackoverflow.com/questions/3346382
;;; My old Gist with my first take on this: https://gist.github.com/492764
;;; Don Jackson's Gist based on the above: https://gist.github.com/1846993
;;; Licence: EPLv1, the same as Clojure
(in-ns 'clojure.tools.trace)
(defn trace-var
"If the specified Var holds an IFn and is not marked as a macro, its
contents is replaced with a version wrapped in a tracing call;
otherwise nothing happens. Can be undone with untrace-var.
In the unary case, v should be a Var object or a symbol to be
resolved in the current namespace.
In the binary case, ns should be a namespace object or a symbol
naming a namespace and s a symbol to be resolved in that namespace."
([ns s]
(trace-var (ns-resolve ns s)))
([v]
(let [v (if (var? v) v (resolve v))
ns (.ns v)
s (.sym v)]
(if (and (ifn? @v) (-> v meta :macro not))
(let [f @v
vname (symbol (str ns "/" s))]
(intern ns
(with-meta s {::traced f})
(fn tracing-wrapper [& args]
(trace-fn-call vname f args))))))))
(defn untrace-var
"Reverses the effect of trace-var / trace-vars / trace-ns for the
given Var, replacing the traced function with the original, untraced
version."
[v]
(let [ns (.ns v)
s (.sym v)]
(alter-meta! (intern ns s ((meta v) ::traced))
dissoc ::traced)))
(defn trace-vars
"Calls trace-var on each of the specified Vars.
The vs may be Var objects or symbols to be resolved in the current
namespace."
[& vs]
(doseq [v vs]
(trace-var v)))
(defn untrace-vars
"Reverses the effect of trace-var / trace-vars / trace-ns for each
of the vs, replacing the traced functions with the original,
untraced versions."
[& vs]
(doseq [v vs]
(untrace-var v)))
(defn trace-ns
"Replaces each function from the given namespace with a version wrapped
in a tracing call. Can be undone with untrace-ns. ns should be a namespace
object or a symbol."
[ns]
(->> ns
ns-interns
vals
(apply trace-vars)))
(defn untrace-ns
"Reverses the effect of trace-var / trace-vars / trace-ns for the
Vars in the given namespace, replacing each traced function from the
given namespace with the original, untraced version."
[ns]
(->> ns
ns-interns
vals
(apply untrace-vars)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment