blob: 1ac00a702ddc581b0e3b4d43fe652f926be595f6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
;;; trace.clj -- simple call-tracing macros for Clojure
;; by Stuart Sierra, http://stuartsierra.com/
;; December 3, 2008
;; Copyright (c) Stuart Sierra, 2008. All rights reserved. The use
;; and distribution terms for this software are covered by the Eclipse
;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this
;; distribution. By using this software in any fashion, you are
;; agreeing to be bound by the terms of this license. You must not
;; remove this notice, or any other, from this software.
;; This file defines simple "tracing" macros to help you see what your
;; 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
#^{:author "Stuart Sierra",
:doc "This file defines simple \"tracing\" macros to help you see what your
code is doing."}
clojure.contrib.trace)
(def
#^{: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. Nested calls to deftrace'd functions will print a
tree-like structure."
[name & definition]
`(do
(def ~name)
(let [f# (fn ~@definition)]
(defn ~name [& args#]
(trace-fn-call '~name f# args#)))))
|