Skip to content

Instantly share code, notes, and snippets.

@fmnoise
Forked from ato/debug.clj
Created July 22, 2017 21:40
Show Gist options
  • Save fmnoise/5547a3815591de89a17904fb36f325e1 to your computer and use it in GitHub Desktop.
Save fmnoise/5547a3815591de89a17904fb36f325e1 to your computer and use it in GitHub Desktop.
Simpler debug-repl that works with unmodified Clojure
;; Inspired by George Jahad's version: http://georgejahad.com/clojure/debug-repl.html
(defmacro local-bindings
"Produces a map of the names of local bindings to their values."
[]
(let [symbols (map key @clojure.lang.Compiler/LOCAL_ENV)]
(zipmap (map (fn [sym] `(quote ~sym)) symbols) symbols)))
(declare *locals*)
(defn eval-with-locals
"Evals a form with given locals. The locals should be a map of symbols to
values."
[locals form]
(binding [*locals* locals]
(eval
`(let ~(vec (mapcat #(list % `(*locals* '~%)) (keys locals)))
~form))))
(defmacro debug-repl
"Starts a REPL with the local bindings available."
[]
`(clojure.main/repl
:prompt #(print "dr => ")
:eval (partial eval-with-locals (local-bindings))))
(comment
;;
;; Some examples
;;
(let [c 1
locals (local-bindings)
d 2]
locals)
;; => {fn__5310 #<user$eval__5309 user$eval__5309@1a65a18>, c 1}
(let [c 1
d 2]
(defn a [b c]
(debug-repl)
d))
(a "foo" "bar")
;; dr => c
;; "bar"
;; dr => d
;; 2
;; dr => *locals*
;; {fn__20 #<user$eval__19 user$eval__19@955cd5>,
;; c "bar",
;; d 2,
;; fn__22 #<user$eval__19$a__21 user$eval__19$a__21@59fb21>,
;; b "foo"}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment