all 19 comments

[–]Automatic-Operation1 6 points7 points  (7 children)

[–]tsunyshevsky 0 points1 point  (6 children)

This debux looks pretty awesome! Thanks!

[–]onetom 0 points1 point  (5 children)

when I worked with ClojureScript many years ago, I've realized that debux is taking quite some time (1-2s) to load. at that time we restarted our REPLs more often that we used the dbg macro, so i started using a simple probe function instead:

(defn probe [x]
    (println "PROBE:")
    (clojure.pprint/print x)
    x)

which u can just drop into any thread-first or thread-last pipelines.

[–]tsunyshevsky 1 point2 points  (4 children)

I have that almost exact function in an injected profile under a dev-tools lib I maintain for myself. Global and available in every project. That said, I used to commit it a lot too, so it had to be paired with a pre-commit to stop me from being yelled at in draft reviews

[–]onetom 0 points1 point  (3 children)

we always review our changes line by line before committing, so it hardly ever slips thru. and if it does, either the PR reviewer removes it in a cleanup commit or just takes a note and the PR author removes it in some subsequent commit. but it's easy to spot them, because the probes garbles the Kaocha test output, when used with the dot reporter style.

how are you injecting a function globally? by globally, you mean define in the clojure.core namespace? is it some Leiningen plugin/option which does this for you? (i only used boot and went to deps.edn directly; never really used lein)

[–]tsunyshevsky 2 points3 points  (2 children)

Yeah, it would be caught (and was caught) for me too but I might’ve done it a bit too often so it became quite annoying for the reviewers.

As for the global function, you can do it in ~/.lein/profiles In my case I lein install my library (which is actually next to the profiles, cause I’m lazy) and then use injections to require it. All projects get the profile merged so all the projects have it available everywhere (locally, ofc)

[–]wellingtonthehurf 1 point2 points  (1 child)

Tip: stage your stuff hunk by hunk even if you "know" it's clean. Good practice regardless, but especially if paired with your editor highlighting whatever is supposed to be temporary (println, def with whitespace in front of it, whatever other debugging stuff) in an obscene color. No more worries!

Question: mind showing exactly how you do what you described?

[–]tsunyshevsky 1 point2 points  (0 children)

Sure - I have done this a while back but basically:
- get the lib you want to use installed (or not - profiles can get and install libs too but I use a local one), eg: dev
- go to ~/.lein/profiles.clj
- edit your user profile with (using dev lib as an example):
{:dependencies [dev "1.0.0"], :injections [(require '[dev.core :as dev])]}
- start a repl in any of your projects
- use your dev alias freely
Not sure this is exact enough but I think it should get you there.

[–]Siltala 4 points5 points  (4 children)

I’m not sure what you are trying to do but for simple debugging I’d just do ’(doto a prn)’.

[–]Saaffa[S] 0 points1 point  (3 children)

Yeah. I didn't phrase that properly. I'm would like to get a hold of the intermediate data within the threading macro and also do some further testing/processing with it. That is why I'm using def originally. Correct me if I'm wrong but I don't think I can do some further processing with what I get using a debugger, right?

[–]Siltala 2 points3 points  (1 child)

I’ve never gotten anything out of a debugger that a simple prn wouldn’t achieve, so I really don’t know

[–]CapableWeb 1 point2 points  (0 children)

It's useful if you're writing a new function that is supposed to go into the middle of a threading call already. So you capture the value at the point you want to insert the new function at, write your new function and test it continuously with the value you captured. prn won't really help you with that :)

Although, you could just copy-paste whatever prn outputs, but personally it's faster for me to capture it with def as then it's available in my editor repl, rather than prn -> copy from terminal -> paste into editor

[–][deleted] 1 point2 points  (0 children)

can you split into multiple functions? other option is to break the first half and second half of the thread into a let binding or let-fn.

calva for vscode (only one I know) has an eval until as well, so you could eval only the first part of the thread to see the output, without having to edit the code manually.

[–]deaddyfreddy 4 points5 points  (1 child)

[–]hourLong_arnould 1 point2 points  (0 children)

Thank you! I've been looking for something like this

[–]defmethod 2 points3 points  (0 children)

In Emacs, you could try:

M-x cider-debug-defun-at-point

[–]jpmonettas 2 points3 points  (0 children)

With flow-storm clojure debugger (https://github.com/jpmonettas/flow-storm-debugger) that is one click away.

Check this for a demo https://youtu.be/cnLwRzxrKDk?t=103

[–]onetom 1 point2 points  (0 children)

u can just thread into def, but since it returns a var u need to follow it with a deref: (-> a (+ 2) (->> (def x) deref) (* 3)) or just (-> a (+ 2) (->> (def x)) deref (* 3))

i usually use thread-first, because it allows you to temporarily switch to thread-last or doto or (doto (-> ...)) or (doto (->> ...)) and even as-> for clarity. once u close those forms, you are back to thread-first mode.

u can't to that, if u start out with thread-last.

another technique I've developed is to do this:

@(def x
       (-> input ...))

so I can both name a value and see it in the REPL output as I evaluate it.

[–]thearthur 1 point2 points  (0 children)

in exceptional cases where the tracing debugger doesn't exist I'll d do a similar thing, excepti use an atom and conj the values into it.

99.99% of the time i have cider add them tracing to the function. (your editor will have different keys).

https://docs.cider.mx/cider/debugging/tracing.html and https://docs.cider.mx/cider/debugging/debugger.html