diff options
author | Stuart Sierra <mail@stuartsierra.com> | 2008-12-03 16:24:19 +0000 |
---|---|---|
committer | Stuart Sierra <mail@stuartsierra.com> | 2008-12-03 16:24:19 +0000 |
commit | 7507083704d10c42281d3d20a409d8c94da0ac60 (patch) | |
tree | 92c8be4f2559da9a6a78d41e02ee13fe957d019f /src/clojure/contrib/trace.clj | |
parent | 561541de1531fc6d7e406c4fe18ad1bea056b0f0 (diff) |
trace.clj: made trace a fn, indent deftraces
* trace is now a function, not a macro (suggested by Stuart Halloway)
* deftrace'd functions produce indented trace output
* tracer function replaces *trace-out*
Diffstat (limited to 'src/clojure/contrib/trace.clj')
-rw-r--r-- | src/clojure/contrib/trace.clj | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/src/clojure/contrib/trace.clj b/src/clojure/contrib/trace.clj index ee7ddd59..7129bc09 100644 --- a/src/clojure/contrib/trace.clj +++ b/src/clojure/contrib/trace.clj @@ -1,7 +1,7 @@ ;;; trace.clj -- simple call-tracing macros for Clojure ;; by Stuart Sierra, http://stuartsierra.com/ -;; June 9, 2008 +;; December 3, 2008 ;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and ;; distribution terms for this software are covered by the Common @@ -16,39 +16,63 @@ ;; code is doing. +;; CHANGE LOG +;; +;; December 3, 2008: +;; +;; * replaced *trace-out* with tracer +;; +;; * made trace a function instead of a macro +;; (suggestion from Stuart Halloway) +;; +;; * added trace-fn-call +;; +;; June 9, 2008: first version + + + (ns clojure.contrib.trace) (def - #^{:doc "PrintStream for trace output. Defaults to System.err."} - *trace-out* (. System err)) - -(defmacro trace - "Prints value of expr to standard error and returns it. Can be - inserted anywhere without affecting surrounding code. Optional - 'name' argument can be used to identify what is being traced." - ([expr] - `(let [value# ~expr] - (. *trace-out* (println - (str "TRACE: " (pr-str value#)))) - value#)) - ([name expr] - `(let [value# ~expr] - (. *trace-out* (println - (str "TRACE " ~name ": " (pr-str value#)))) - value#))) + ^{:doc "Current stack depth of traced function calls."} + *trace-depth* 0) + +(defn tracer + "This function is called by trace. Prints to standard output, but + may be rebound to do anything you like. 'name' is optional." + [name value] + (println (str "TRACE" (when name (str " " name)) ": " value))) + +(defn trace + "Sends name (optional) and value to the tracer function, then + returns value. May be wrapped around any expression without + affecting the result." + ([value] (trace nil value)) + ([name value] + (tracer name (pr-str value)) + value)) + +(defn trace-indent + "Returns an indentation string based on *trace-depth*" + [] + (apply str (take *trace-depth* (repeat "| ")))) + +(defn trace-fn-call + "Traces a single call to a function f with args. 'name' is the + symbol name of the function." + [name f args] + (let [id (gensym "t")] + (tracer id (str (trace-indent) (pr-str (cons name args)))) + (let [value (binding [*trace-depth* (inc *trace-depth*)] + (apply f args))] + (tracer id (str (trace-indent) "=> " (pr-str value))) + value))) (defmacro deftrace "Use in place of defn; traces each call/return of this fn, including - arguments." + arguments. Nested calls to deftrace'd functions will print a + tree-like structure." [name & definition] `(let [f# (fn ~@definition)] (defn ~name [& args#] - (let [id# (gensym "t")] ; identifier for this invocation - (. *trace-out* - (println (str "TRACE " id# ": " ~(str name) - " called with " (pr-str args#)))) - (let [value# (apply f# args#)] ; call original fn - (. *trace-out* - (println (str "TRACE " id# ": " ~(str name) - " returned " (pr-str value#)))) - value#))))) + (trace-fn-call '~name f# args#)))) |