0
# Development Tools
1
2
Development and debugging utilities through specialized namespaces: clojure.stacktrace for Clojure-oriented stack trace printing, clojure.inspector for graphical data structure inspection, and clojure.template for code templating and generation.
3
4
## Capabilities
5
6
### Stack Trace Analysis (clojure.stacktrace)
7
8
Tools for printing and analyzing stack traces with Clojure-specific formatting and information extraction.
9
10
```clojure { .api }
11
(clojure.stacktrace/root-cause throwable)
12
;; Returns the last 'cause' Throwable in a chain of Throwables
13
;; throwable: Throwable to analyze
14
;; Returns: root cause Throwable
15
16
(clojure.stacktrace/print-trace-element stack-trace-element)
17
;; Prints a Clojure-oriented view of one stack trace element
18
;; stack-trace-element: StackTraceElement to print
19
;; Returns: nil (prints to *out*)
20
21
(clojure.stacktrace/print-throwable throwable)
22
;; Prints the class and message of a Throwable, includes ex-data if present
23
;; throwable: Throwable to print
24
;; Returns: nil (prints to *out*)
25
26
(clojure.stacktrace/print-stack-trace throwable)
27
;; Prints stack trace for throwable with Clojure-specific formatting
28
;; throwable: Throwable to print trace for
29
;; Returns: nil (prints to *out*)
30
31
(clojure.stacktrace/print-cause-trace throwable)
32
;; Prints stack trace including all causes in the exception chain
33
;; throwable: Throwable to print full cause chain for
34
;; Returns: nil (prints to *out*)
35
36
(clojure.stacktrace/e)
37
;; Prints stack trace of most recent exception (*e)
38
;; Returns: nil (prints to *out*)
39
```
40
41
### Data Structure Inspector (clojure.inspector)
42
43
Graphical inspection tools for exploring Clojure data structures using Swing components.
44
45
#### Core Inspector Functions
46
47
```clojure { .api }
48
(clojure.inspector/inspect data)
49
;; Opens graphical inspector window for data structure
50
;; data: Clojure data structure to inspect
51
;; Returns: inspector component
52
53
(clojure.inspector/inspect-tree data)
54
;; Opens tree view inspector for hierarchical data
55
;; data: nested data structure
56
;; Returns: JFrame with tree view
57
58
(clojure.inspector/inspect-table data)
59
;; Opens table view inspector for tabular data
60
;; data: sequence of maps or map-entry collections
61
;; Returns: JFrame with table view
62
```
63
64
#### Inspector Data Model Functions
65
66
```clojure { .api }
67
(clojure.inspector/atom? x)
68
;; Returns true if x is an atomic value (not a collection)
69
;; x: value to test
70
;; Returns: boolean
71
72
(clojure.inspector/collection-tag x)
73
;; Returns tag indicating collection type for inspector display
74
;; x: value to categorize
75
;; Returns: keyword (:entry, :seqable, :seq, or :atom)
76
77
(clojure.inspector/tree-model data)
78
;; Creates TreeModel for Swing JTree component
79
;; data: nested data structure
80
;; Returns: javax.swing.tree.TreeModel
81
82
(clojure.inspector/list-model provider)
83
;; Creates list model for inspector interface
84
;; provider: data provider function
85
;; Returns: list model for Swing components
86
```
87
88
### Code Templates (clojure.template)
89
90
Macros for generating repetitive code patterns using template expansion.
91
92
```clojure { .api }
93
(clojure.template/apply-template argv expr values)
94
;; For use in macros - recursively replaces argument symbols in expr with values
95
;; argv: argument vector (symbols)
96
;; expr: quoted expression using symbols from argv
97
;; values: sequence of replacement values
98
;; Returns: modified expr with substitutions
99
100
;; Macro for repeated template expansion
101
(clojure.template/do-template argv expr & values)
102
;; Repeatedly copies expr for each group of arguments in values
103
;; argv: argument vector as in defn
104
;; expr: template expression
105
;; values: arguments automatically partitioned by argv length
106
;; Returns: do block with expanded expressions
107
```
108
109
**Usage Examples:**
110
111
```clojure
112
;; Stack trace analysis examples
113
(require '[clojure.stacktrace :as st])
114
115
;; Analyze exception chain
116
(try
117
(throw (Exception. "Inner" (RuntimeException. "Root cause")))
118
(catch Exception e
119
(st/root-cause e)))
120
;; => #<RuntimeException java.lang.RuntimeException: Root cause>
121
122
;; Print detailed stack trace
123
(try
124
(/ 1 0)
125
(catch Exception e
126
(st/print-cause-trace e)))
127
;; Prints full cause chain with Clojure-formatted stack trace
128
129
;; Print most recent exception
130
(/ 1 0) ; causes exception
131
(st/e) ; prints stack trace of *e
132
133
;; Custom exception with data
134
(try
135
(throw (ex-info "Custom error" {:code 404 :resource "/api/users"}))
136
(catch Exception e
137
(st/print-throwable e)))
138
;; Prints: clojure.lang.ExceptionInfo: Custom error
139
;; {:code 404, :resource "/api/users"}
140
141
;; Data structure inspector examples
142
(require '[clojure.inspector :as inspect])
143
144
;; Inspect nested data structure
145
(def sample-data
146
{:users [{:id 1 :name "Alice" :roles [:admin :user]}
147
{:id 2 :name "Bob" :roles [:user]}]
148
:config {:database {:host "localhost" :port 5432}
149
:logging {:level :info :file "app.log"}}})
150
151
;; Open graphical inspector (requires GUI environment)
152
(inspect/inspect sample-data)
153
154
;; Inspect as tree view
155
(inspect/inspect-tree sample-data)
156
157
;; Inspect tabular data as table
158
(inspect/inspect-table (:users sample-data))
159
160
;; Check data characteristics
161
(inspect/atom? 42) ; => true
162
(inspect/atom? [1 2 3]) ; => false
163
(inspect/collection-tag {:a 1}) ; => :seqable
164
165
;; Code template examples
166
(require '[clojure.template :as tmpl])
167
168
;; Apply template function (for macro writing)
169
(tmpl/apply-template '[x y] '(+ x y (* x y)) '[3 4])
170
;; => (+ 3 4 (* 3 4))
171
172
;; Template macro usage
173
(macroexpand
174
'(tmpl/do-template [op a b]
175
(defn ~(symbol (str "test-" op)) [] (~op ~a ~b))
176
+ 2 3
177
- 5 2
178
* 4 6))
179
;; Expands to:
180
;; (do
181
;; (defn test-+ [] (+ 2 3))
182
;; (defn test-- [] (- 5 2))
183
;; (defn test-* [] (* 4 6)))
184
185
;; Real-world template example - generating multiple similar functions
186
(tmpl/do-template [name pred type-name]
187
(defn ~name [x]
188
(if (~pred x)
189
x
190
(throw (IllegalArgumentException.
191
(str "Expected " ~type-name ", got " (type x))))))
192
193
ensure-string string? "string"
194
ensure-number number? "number"
195
ensure-vector vector? "vector"
196
ensure-map map? "map")
197
198
;; Results in:
199
;; (defn ensure-string [x] ...)
200
;; (defn ensure-number [x] ...)
201
;; (defn ensure-vector [x] ...)
202
;; (defn ensure-map [x] ...)
203
204
;; Template for test generation
205
(tmpl/do-template [input expected]
206
(is (= ~expected (my-function ~input)))
207
208
"hello" "HELLO"
209
"world" "WORLD"
210
"" ""
211
nil nil)
212
213
;; Template for property access
214
(tmpl/do-template [prop-name getter setter field]
215
(do
216
(defn ~getter [obj] (~field obj))
217
(defn ~setter [obj val] (assoc obj ~field val)))
218
219
name get-name set-name :name
220
age get-age set-age :age
221
email get-email set-email :email)
222
223
;; Working with inspector programmatically
224
(defn debug-inspect [label data]
225
(println (str "Inspecting: " label))
226
(inspect/inspect data)
227
data) ; return data for chaining
228
229
;; Use in threading macro
230
(-> {:a 1 :b 2}
231
(assoc :c 3)
232
(debug-inspect "after adding :c")
233
(dissoc :a)
234
(debug-inspect "after removing :a"))
235
```