Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f1c9f90

Browse files
committed
Revises tracing recipe for style and new conventions
1 parent 731065c commit f1c9f90

File tree

1 file changed

+97
-66
lines changed

1 file changed

+97
-66
lines changed

kitchen-sink/tracing/tracing.asciidoc

Lines changed: 97 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,115 +4,146 @@
44

55
===== Problem
66

7-
You need to trace the behavior of your code.
7+
You want to trace the execution of your code, in order to see what it is doing.
88

99
===== Solution
1010

11-
Use +clojure.tools.trace/trace+ to trace a value.
12-
[source,clojure]
13-
----
14-
(use 'clojure.tools.trace)
15-
(trace (+ 2 2))
16-
;; TRACE: 4
17-
;; 4
18-
----
11+
Use +clojure.tools.trace/trace+ to print a value and return it.
1912

20-
When tracing a value you can assign a tag to a trace to give additional information.
2113
[source,clojure]
2214
----
23-
(def add-tag "The point of the addition")
24-
(trace add-tag (+ 2 2))
25-
;; TRACE The point of the addition: 4
26-
;; 4
15+
(ns cookbook.core
16+
(:use clojure.tools.trace))
17+
18+
(doall (map #(* 2 (trace %)) (range 10)))
19+
;; -> (0 2 4 6 8 10 12 14 16 18)
20+
;; *out*
21+
;; TRACE: 0
22+
;; TRACE: 1
23+
;; TRACE: 2
24+
;; TRACE: 3
25+
;; TRACE: 4
26+
;; TRACE: 5
27+
;; TRACE: 6
28+
;; TRACE: 7
29+
;; TRACE: 8
30+
;; TRACE: 9
2731
----
2832

29-
Use +trace-forms+ to trace a combination of forms.
33+
Use tags to give additional context to the output.
3034

3135
[source,clojure]
3236
----
33-
(trace-forms (+ 1 2 (/ 6 2)))
37+
(defn add
38+
[a b]
39+
(+ (trace "a" a) (trace "b" b)))
40+
41+
(add 2 4)
3442
;; -> 6
43+
;; *out*
44+
;; TRACE a: 2
45+
;; TRACE b: 4
3546
----
36-
Wait, nothing special happens. Lets try that again with some code that fails.
47+
48+
Use +trace-forms+ to trace a series of expressions, some of which may
49+
fail.
50+
3751
[source,clojure]
3852
----
3953
(trace-forms (+ 1 2 (/ 6 0)))
40-
;;ArithmeticException Divide by zero
41-
;; Form failed: (/ 6 0)
42-
;; Form failed: (+ 1 2 (/ 6 0))
43-
;; clojure.lang.Numbers.divide (Numbers.java:156)
54+
;; -> (throws an exception...)
55+
;; *out*
56+
;; ArithmeticException Divide by zero
57+
;; Form failed: (/ 6 0)
58+
;; Form failed: (+ 1 2 (/ 6 0))
59+
;; clojure.lang.Numbers.divide (Numbers.java:156)
4460
----
45-
With a form failing you now get a trace following the execution of the forms.
4661

47-
Use +deftrace+ to define a traced function.
62+
If no exception occurs, `trace-forms` produces no output.
63+
64+
Use `deftrace` in place of `defn` to define a traced function.
65+
4866
[source,clojure]
4967
----
50-
(deftrace divider [x y] (/ x y))
51-
(divider 2 (+ 1 1))
52-
;; TRACE t1467: (divider 2 2)
68+
(deftrace divide [x y] (/ x y))
69+
(divide 2 (+ 1 1))
70+
;; -> 1
71+
;; *out*
72+
;; TRACE t1467: (divide 2 2)
5373
;; TRACE t1467: => 1
54-
;; 1
5574
----
5675

57-
Use +trace-vars+ and +untrace-vars+ to enable or disable tracing of a function.
76+
Use +trace-vars+ and +untrace-vars+ to enable or disable tracing of an
77+
existing function.
78+
5879
[source,clojure]
5980
----
60-
(defn adder [x y] (+ x y))
61-
(trace-vars cookbook.core/adder)
62-
(adder 2 2)
63-
;; TRACE t1309: (cookbook.core/adder 2 2)
81+
(defn add [x y] (+ x y))
82+
(trace-vars cookbook.core/add)
83+
(add 2 2)
84+
;; -> 4
85+
;; *out*
86+
;; TRACE t1309: (cookbook.core/add 2 2)
6487
;; TRACE t1309: => 4
65-
;; 4
66-
(untrace-vars cookbook.core/adder)
67-
(adder 2 2)
68-
;; 4
88+
(untrace-vars cookbook.core/add)
89+
(add 2 2)
90+
;; -> 4
6991
----
7092

71-
Use +trace-ns+ and +untrace-ns+ to enable or disable tracing of all functions in a namespace.
93+
Use +trace-ns+ and +untrace-ns+ to enable or disable tracing of all
94+
functions in a namespace.
95+
7296
[source,clojure]
7397
----
74-
(trace-ns (create-ns 'cookbook.core))
75-
(adder 2 (divider 6 3))
76-
;; TRACE t1276: (cookbook.core/divider 6 3)
98+
(trace-ns 'cookbook.core)
99+
(add 2 (divide 6 3))
100+
;; -> 4
101+
;; *out*
102+
;; TRACE t1276: (cookbook.core/divide 6 3)
77103
;; TRACE t1276: => 2
78-
;; TRACE t1277: (cookbook.core/adder 2 2)
104+
;; TRACE t1277: (cookbook.core/add 2 2)
79105
;; TRACE t1277: => 4
80-
;; 4
81-
(untrace-ns (create-ns 'cookbook.core))
82-
(adder 2 (divider 6 3))
83-
;; 4
106+
107+
(untrace-ns 'cookbook.core)
108+
(add 2 (divide 6 3))
109+
;; -> 4
84110
----
85-
Note the use of +create-ns+ which will return the +Namespace+ instance given a namespace that already exists.
86111

87112
===== Discussion
88-
Trace functionality will usually work in two different ways, as a pass through decoration of values, as with +trace+ or by changing the root-binding of a +var+ such in the case of +trace-var+ and +trace-ns+.
89113

90-
It is worth noting that the +clojure.tools.trace/trace+ function can be rebound. By doing that you can change how traces are done and to where. The default implementation will print to the standard output, but you can easily change that.
91-
[source,clojure]
92-
----
93-
(ns clojure.tools.trace)
94-
(defn tracer [name value]
95-
(spit "trace.txt"
96-
(str name ": " value "\n") :append true))
97-
----
98-
With this definition of +trace+, any call made to +trace+ will add a line with the trace information to the "trace.txt" file. In this quick and easy way you have added logging of the traces, which sometimes might be sufficient instead of adding a dependency to a more sophisticated logging library.
114+
`tools.trace` provides two approaches to tracing the execution of
115+
code: explicitly tracing specific values, or through re-binding vars
116+
or entire namespaces. These low-level and high-level approaches are
117+
both effective tools for tracking down tough bugs.
99118

100-
Note that if you during development re-define a traced function you also need to re-enable the tracing for that function.
119+
For example, tracing can be a useful tool when trying to get your head
120+
around a `reduce` operation:
101121

102-
Tracing can be a useful tool when trying to get your head around a reduction.
103122
[source,clojure]
104123
----
105-
(trace-vars cookbook.core/adder)
106-
(reduce adder [1 2 3])
107-
;; TRACE t1338: (cookbook.core/adder 1 2)
124+
(trace-vars cookbook.core/add)
125+
(reduce add [1 2 3])
126+
;; -> 6
127+
;; *out*
128+
;; TRACE t1338: (cookbook.core/add 1 2)
108129
;; TRACE t1338: => 3
109-
;; TRACE t1339: (cookbook.core/adder 3 3)
130+
;; TRACE t1339: (cookbook.core/add 3 3)
110131
;; TRACE t1339: => 6
111-
;; 6
112132
----
113-
This will allow you to follow along in each step of the reduction.
114133

115-
There is a time and a place for everything, of course, and production isn't the most appropriate environment for you to flex your new-found Clojure-tracing skills. Typical places you'll make use of tracing are during development or while diagnosing a hard-to-catch bug you've been able to reproduce locally, but not diagnose. Include the +core.trace+ library in your project's +:dev+ profile to make tracing available where appropriate.
134+
This allows you to follow each step of the reduction.
135+
136+
CAUTION: When using `trace-vars` or `trace-ns`, the traced version of
137+
a function is lost when the namespace is reloaded and the underlying
138+
var is redefined. You must remember to re-establish the traced
139+
versions, if necessary, after reloading a namespace.
140+
141+
It is not advisable to deploy production code with tracing in
142+
place. Tracing is most suited to development and debugging,
143+
particularly from the REPL. Include +tools.trace+ in your
144+
`project.clj`'s +:dev+ profile to make tracing available only to
145+
development tasks.
116146

117147
===== See also
118-
* See the documentation for https://github.com/clojure/tools.trace[+clojure.tools.trace+]
148+
149+
* Documentation for https://github.com/clojure/tools.trace[+clojure.tools.trace+]

0 commit comments

Comments
 (0)