Fork me on GitHub
#off-topic
<
2019-01-05
>
vemv20:01:56

Could one implement a quick-and-dirty debugger with the following approach?

(defn debugger []
  (nrepl.server/start-server :port 7888) ;; this should be a blocking call. The nREPL server remains open until the first client that connects to it tells it to quit
  )
So, I place a (debugger) call anywhere, execution stops there, and I can lein repl :connect localhost:7888 from a secondary terminal Sounds possible? Anyone doing that already? Would be particularly interesting if the spawned nrepl captured the local bindings of the parent

vemv21:01:04

This guy had the same idea and seemed to have some luck... first answer is useful https://stackoverflow.com/questions/49599694/how-to-see-clojure-local-variables-in-local-repl

eggsyntax19:01:58

I use this:

(defn contextual-eval [ctx expr]
  (eval
   `(let [~@(mapcat (fn [[k v]] [k `'~v]) ctx)]
      ~expr)))

(defn readr [prompt exit-code]
  (let [input (clojure.main/repl-read prompt exit-code)]
    (if (= input :q)
      exit-code
      input)))

(defmacro local-context []
  (let [symbols (keys &env)]
    (zipmap (map (fn [sym] `(quote ~sym)) symbols) symbols)))

(defmacro break
  ":q to exit"
  []
  `(clojure.main/repl
    :prompt #(print "debug => ")
    :read readr
    :eval (partial contextual-eval (local-context))))

eggsyntax19:01:14

Believe I stole that from somewhere, but I apparently didn't make a note of where. Works fine for me 🙂

eggsyntax19:01:56

Looks like I stole it from Joy of Clojure, as cited here: https://gist.github.com/leobm/6061734

vemv20:01:47

nice! debug_repl linked above uses approximately the same code, likely that it took it from there too