Fork me on GitHub
#clojure
<
2024-04-08
>
jasonjckn02:04:06

Is there ROI on switching to a 'real' clojure debugger (and which would you recommend), I have a very ingrained habit of 'debugging my code via REPL + adding inline defs temporarily and never seem to knock the habit, even though i tell myself i'll find a better way. The REPL works pretty well.., just need a nudge if its worth it.

šŸ’Æ 2
Ben Sless02:04:31

I use a debugger quite rarely, but the ROI is worth it. Sometimes you just need to be able to step through the program's execution, look at local variables, dig into nasty data. Maybe you have a weird bug inside a go block and only FlowStorm can help. Then the ROI is infinite. If you're an Emacs user the debugger + inspector offer a very tight and well integrated experience. Give it a shot

ā¤ļø 1
seancorfield02:04:40

I'll just counter and say that in 13+ years of using Clojure, I've never felt the need to reach for more than REPL + println (although now I use REPL + tap> + Portal).

ā¤ļø 1
āž• 3
jasonjckn02:04:58

@UK0810AQ2 i'm an emacs user, between cider, flowstorm, and inspector, any preferences, or they're all useful for different reasons

seancorfield02:04:24

I admit, I've never tried FlowStorm...

seancorfield02:04:57

But I never really liked step debugging even back when I used languages where it really was the only option šŸ˜ž

āž• 1
jasonjckn02:04:15

at least you've tried something šŸ™‚ i've just done the same thing I was doing since day 1 of clojure, nothings changed in this regard in several years.

seancorfield02:04:34

tap> changed my (debugging) life šŸ™‚

jasonjckn02:04:41

i'll check it out

Alex Miller (Clojure team)02:04:43

Working on Clojure itself, I am almost always in a mix of Java and Clojure, and the IntelliJ debugger is a big boost for me. But when Iā€™m using only Clojure, I rarely bother with a debugger.

ā¤ļø 1
vemv03:04:50

Given you mention cider, a new approach is to use cider-log-mode, which is integrated with the cider Inspector. My workflow in real world projects goes as follow: ā€¢ Log stuff with a context (Logback MDC context, timbre/with-context+) in strategic places (middleware. http clients, sql queries, some hand-picked places) ā€¢ See the logged stuff right into emacs ā€¢ When needed, hit RET into a line, then the context will pop up into the Inspector

vemv03:04:24

I find it cool as it bridges old-style logging with application-wide data tracing which is similar to flowstorm, but less exhaustive (which can feel more focused - I only follow data in the places where I think it's worthwhile)

šŸ‘ 1
Ben Sless03:04:21

If you're an Emacs user, just give cider's debugger a shot, it's awesome and at the tip of your fingers. That's 99.9% of my debugging needs

šŸ‘ 1
āž• 1
practicalli-johnny07:04:06

I tap> Clojure evaluation and mlog log events to portal automatically, which gives me all I need (also works with any repl connected editor) When I was learning I did find Cider debug tool useful when I messaged up a larger loop recur expression, or similar iterative expression, e.g. https://practical.li/spacemacs/debug-clojure/cider-debug/ Although now I still mostly use the repl and break down the loop recur (if I didn't write it)

šŸ‘ 1
Lari Saukkonen14:04:41

I use either snitch (https://github.com/AbhinavOmprakash/snitch) or cider debugger if I need more than inline defs, which I rarely do.

šŸ‘ 2
zimablue12:04:13

how do you get pprint to split /strings/ above a max width?

p-himik13:04:46

Pretty sure clojure.pprint/pprint doesn't do that by itself. You can try overriding (defmethod print-method String ...) with your own impl that does that, but it'll affect other printing as well.

p-himik13:04:18

I would try a different library first. Perhaps zprint can do that, it has an insane amount of options.

zimablue13:04:29

thanks I could instead post-process the result: splitlines any trailing strings over widthmax get "" -> "" "" treatment with matching indent below, so still valid /equiv EDN? doesn't handle preusmably the same problem with integers/keywords but if you can handle trailing strings it's more than an 80-20 probably?

p-himik13:04:18

I would still check out zprint first. :)

šŸ‘ 1
adham14:04:41

Hey all I have a question regarding https://github.com/clojure/core.cache, what is the best practice regarding where to create the cache, is it 1. Per namespace where it is used 2. In a namespace and then referred when needed

p-himik14:04:28

That's exactly the same question as where to create a non-public function. Just use the same reasoning you'd use there. Depending on your development approach, storing the cache in the same ns where it's used under a plain def and not defonce might make things easier when you reload the whole namespace.

adham14:04:44

I see, that makes it a bit easier to decide, thank you for the viewpoint!

yuhan16:04:22

Is there any way to get the printer to output qualified keywords using the ::foo syntax instead of :some.overly.verbose.namespace/foo? Just looking for a way to improve readablility of these forms at the REPL, much the same function as they serve in a source file by reducing visual clutter.

p-himik17:04:09

Note that this affects all printing calls happening in that REPL session:

user=> (import '( Writer))
java.io.Writer
user=> (defmethod print-method clojure.lang.Keyword [o ^Writer w] (.write w (if (= (name (ns-name *ns*)) (namespace o)) (str "::" (name o)) (str o))))
#object[clojure.lang.MultiFn 0x1ee29c84 "clojure.lang.MultiFn@1ee29c84"]
user=> :dev/a
:dev/a
user=> (ns dev)
nil
dev=> :dev/a
::a
A more robust option that doesn't affect other print calls is to run your own REPL via an explicit call to clojure.main/repl with the right :print option. If you're using nREPL, there's probably an existing middleware that does it, or you can make one yourself.

ā­ 1
yuhan17:04:17

That works great :) It feels wrong to override the global print-method in that way, but seems like that's how cider-nrepl's middleware does it in order to output functions / atoms etc. more readably.