Skip to content

Instantly share code, notes, and snippets.

@michalmarczyk
Created July 27, 2010 19:55
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save michalmarczyk/492764 to your computer and use it in GitHub Desktop.
Save michalmarczyk/492764 to your computer and use it in GitHub Desktop.
;;; See the inspirational SO question: http://stackoverflow.com/questions/3346382
(require 'clojure.contrib.trace)
(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]
(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 @v})
(let [f @v] (fn [& args]
(clojure.contrib.trace/trace (str "entering: " s))
(apply f args))))))
(defn untrace-ns
"Reverses the effect of trace-ns, replacing each traced function from the
given namespace with the original, untraced version."
[ns]
(doseq [s (keys (ns-interns ns))
:let [v (ns-resolve ns s)]
:when (:traced (meta v))]
(alter-meta! (intern ns s (:traced (meta v)))
dissoc :traced)))
@dcj
Copy link

dcj commented Feb 17, 2012

if you would like to contact me directly, and email sent to gmail user don dot jackson should do the trick :-)

@dcj
Copy link

dcj commented Feb 17, 2012

Not sure if I should respond here or on the new Gist. Decided to stay here for now...
I just looked through your new code, briefly. It looks really good!
I will need to study it in more detail, but I love the direction in which you are heading.

Somehow I discovered alter-var-root yesterday, and I used that in my code. I do not yet understand the difference between alter-var-root versus intern.
But if something is already interned, then it kind of feels like altering that thing might be a good way to go versus creating a new thing with the same name.
But I have no idea if this is a valid feeling. Any thoughts?

The other thing that I noticed when working on this yesterday was that when you obtain the metadata of a function, the namespace of that function is sitting right there! (as is its symbol). In functions like ns-resolve and intern where it is asking for the namespace, would it be better to just give it the namespace that is clearly associated with the original function, by obtaining that from the original metadata?

One underlying motivation behind both the above points is that there is a function that already exists. The goal of trace-fn/trace-var is to REPLACE the existing thing with something new, and later, to put it back EXACTLY as it was before (if possible). It seems like we doing that, but I'm just wondering if we are doing everything we can to do so....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment