Define the problem first
Since I started with Debugging clojure, I have used to use prn
to see results. I also used #dbg
in calva, which looks like a traditional debug mode and good as well. However, I'd like to improve my debugging with REPL driven development and be more productive. I have searched for things and end up with finding nice combinations, trace + portal.
Understanding tap>
trace is written by hlship and a README contains motivations. I find it strong to leave trace codes in production because the debug is traced when the set-up is on. The other point is it let us know where it is traced. If you experienced with tap>
, it's hard to trace a bunch of values in a tap.
[portal] is written by djblue. It connects to REPL and can navitate data. Obviously, it's related with UI stuff and navigation tool.
Easy approach to debug.
(defn inspector
[x]
(prn x)
x)
(defn calls
[]
(inspector "called"))
(defn calls>
[]
(-> {:value 1}
(update :value inc)
inspector
(assoc :after true)))
(defn calls>>
[]
(->> (range 10)
(map inc)
inspector
(partition 2)))
(comment
(calls)
;; "called"
(calls>)
;; {:value 2}
(calls>>)
;; (1 2 3 4 5 6 7 8 9 10)
)
tap>
is always good enough but a little bit hard to label.
(def debug-atom (atom []))
(add-tap (fn [value] (swap! debug-atom #(conj % value))))
(comment
(tap> 1)
@debug-atom
;; [1]
(tap> {:age 31
:name "jungwoo"})
@debug-atom)
;; [1 {:age 31
:name "jungwoo"}]
This sample code is from here. I've forked this repo and changed just few line to make it easy threading macro.
(defn calls-trace
[]
(trace :msg "called"))
(defn calls-trace>
[]
(-> {:value 1}
(update :value inc)
(trace> :label :post-inc)
(assoc :after true)))
(defn calls-trace>>
[]
(->> (range 10)
(map inc)
(trace>> :label :post-inc)
(partition 2)))
(comment
(calls-trace)
;; no output
(trace/setup-default)
;; Reload this NS to test the remainder:
(calls-trace)
;; {:in my-only-trace/calls-trace
;; :line 7
;; :thread "nREPL-session-90a76836-b2ce-4d07-86db-23db11474218"
;; :msg "called"}
(calls-trace>)
;; {:in my-only-trace/calls-trace>
;; :line 13
;; :thread "nREPL-session-90a76836-b2ce-4d07-86db-23db11474218"
;; :%value% {:value 2}
;; :label :post-inc}
(calls-trace>>)
;; {:in my-only-trace/calls-trace>>
;; :line 20
;; :thread "nREPL-session-90a76836-b2ce-4d07-86db-23db11474218"
;; :%value% (1 2 3 4 5 6 7 8 9 10)
;; :label :post-inc}
)
As I mentioned, portal is the UI tool with add-tap
so example code is basically same but we need to launch portal like below.
(comment
(calls-trace)
(trace/setup-default)
;; Reload this NS to test the remainder:
(do (ns dev)
(def portal ((requiring-resolve 'portal.api/open)
{:launcher :vs-code
:portal.launcher/window-Title (System/getProperty "user.dir")}))
(add-tap (requiring-resolve 'portal.api/submit)))
(calls-trace)
(calls-trace>)
(calls-trace>>))
I was on VS code so the new window is shown up!
It really depends on cases. I use all of those. This is an whole example code.
Discuss this post here.
Published: 2022-10-11
Tagged: Clojure