We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
Analysis Summary
Worth Noting
Positive elements
- This video provides a practical, no-nonsense guide to interactive debugging in Clojure, specifically showing how to inject values into a running process.
Influence Dimensions
How are these scored?About this analysis
Knowing about these techniques makes them visible, not powerless. The ones that work best on you are the ones that match beliefs you already hold.
This analysis is a tool for your own thinking — what you do with it is up to you.
Related content covering similar topics.
Starting a fresh Clojure project with Neovim REPL driven development
Olical
Clojure on IntelliJ: Using open-source plugins - Fücher
ClojureTV
Ritz, The Missing Clojure Tooling Hugo Duncan
Zhang Jian
ast-grep
DevOnDuty
How Clojure (and ClojureScript) REPL connections work - feat the creator of Calva!
Daniel Amber
Transcript
okay hi so uh i'm the author of conjure and conjure is a neovim lisp development toolkit that allows you to interactively work with many different languages um one of those languages uh is the the main one closure and it recently got support for uh debuggers so you can actually debug a closure program while connected to it over a rebel uh using the cider and rebel debugger middleware this is actually going to be superseded at some point by closure dap which is something that i'm yet to write but will allow you to use debug adapter protocol uis for your editor to be able to debug closure code over an mrapple um this means that you can use any editor any repel tooling whatever you want but it will play nicely with conjure so it's separate to conjure but we'll complement it nicely and this will really replace the debugger support inside conjure um which is why the debugger support encounter is so rough and simple um because it just seems like a waste of time to implement so much of that and then replace it with something so much better that is a lot easier to do but in this video um i'm going to quickly show you how to set a breakpoint and actually step into your code change your value inspect some values and get out so i'm not going to exhaustively go across everything because i don't fully understand the side of debugger protocol either but i'm going to show you the important parts that should be enough to keep you going and something that i only realized recently that is very key is i've recommended this in the past this debug key what this hash debug does is sets a breakpoint all the way through your code so it doesn't just set one breakpoint it doesn't just set a breakpoint at the point that you type it it sets it at this layer it sets it on the plus it sets it on the a and it sets it on the b so it sets it on every single symbol every single form all the way down the tree recursively um as i understand it the different one you can use is just hash break so we're going to use break in the examples because it's a lot simpler it only sets one breakpoint and then you can inspect that single value i feel like it's a bit unpredictable and a bit more intuitive especially with um conjures should we say simple ui so you can actually go to this wiki page here so if you go to the country repo you go to wiki um and you go to closure and report cider debugger uh you can see all this information and you can also see a link to the closure dap repo which is under development and we're actually going to connect to that now so we're actually going to connect to it and we're going to debug it even though it's just a hello world still right now so over in my editor to reset the log we have a nrapple started so inside the project we have a development script that started a repel with an mripple port open and i've opened my editor with conjurer installed and i'm going to connect that i'm going to start a fresh one so may not clj and let's get the log open and we want to connect to this port let's restart this there we go so we are connected to our repl i can evaluate code excellent so we have a run function here that is very very simple all it does it says hello it takes some options you can run it down here so as an example let's execute that we can see that it's printed uh the options so p print opts the ops we gave it were x of 10. and it also printed hello twitch and youtube uh with a x coming out of the ops so it pulled the x out now what we're going to do is step into this point and replace the number so we're still going to pass in x of 10 we're still going to have the code that says x of 10 or x of ops which will be 10 um but we're going to replace it with another number so before we do that we've got to initialize the debugger with conjug clj debug in it uh you will probably want to set this kind of thing to a mapping uh or automatically run it on when you open a file if you're using this off like quite often i'm not using it too often so i didn't bother to put all these behind mappings but you might want to do that yourself so let's run that command i'm just going to copy it just a bit quicker so conjure clj debug init execute that we've initialized the side of debugger so everything at the moment is still the same like i can evaluate stuff nothing's different but what i can do is go in here and put break reload the code so i just reloaded that function and go and run it again and everything pauses so the first line runs we get print opts and we see the ops so x10 cool we knew that that's not surprising uh let's print the locals and we do that by running conjure clj debug input which you can see here it says that we respond with this command and some input and the inputs we can give it right now are here and these vary over time but it's going to tell you what you can give it uh each step so let's uh print the locals and our locals are opts with x10 in it again we knew this but if you were writing a more complex function if you had like a few hundred local variables and they changed all the time and there was an argument coming in from something else and some state from somewhere else this would actually give you a really good view of like exactly the state of your system without having to put print lines or anything in so we can see our ops let's replace this value so at the moment this would respond with 10 if we evaluate this code let's replace it with 20. i'm going to do that with inject so we run input inject and it says expression to inject so what do we want to put in this place let's do 20 and it finished the rest of the code so it continued from that point onwards um and replaced it with 20. so it ended up printing x10 then 20. um and now i'm not using debug here because uh if we use debug it's as if the equivalent is this oh no hang on there we go so when you use debug it's as if you wrote this which could be useful um i think it's more useful when you're inside cider in emacs um so i think when you're using a ui that will actually kind of move the cursor highlight things point out exactly where you are i think that's more valuable because you'll actually see oh i'm here and all these things have been instrumented okay i can see that country doesn't give you that information um because like i said i'm going to be implementing something else that supersedes this so i think you should just stick to using break don't use debug and just put a break point on the exact point you're interested in you can still inspect the locals you can still replace things but you should keep it simple if you use debug it's doing more than you realize and that's going to get quite confusing because you have to step in and out of the forms so yeah i i don't think that's worth it right now i think break is good enough so that's all there is to it at the moment really there's not much else to show that's how you pause your program inspect values and change them on the fly it's not all of the features it's like nothing in comparison to sidereel's ui so in the emacs version it's not an ide but those features will come when uh closure dap is done and we have uh mvim dap ui support so when this rupo is done we're going to drop all of the support uh that i just showed you uh and we're actually gonna be able to use stuff like this instead doesn't that look so much better like it i couldn't implement all this alongside all of my other work i don't have the time for that so i'm going to implement the thing that allows you to use this with closure which should be a lot less work and should work very nicely so yeah that's all for this video just a quick demonstration of running the closure debugger inside conjure um come and check it out uh if you're already using conjure then maybe you didn't know this feature existed and it might save you a lot of work at work i hope have a good day
Video description
A quick example of how to use the Conjure debugger. https://github.com/Olical/conjure Recorded live at https://www.twitch.tv/olicaluk https://github.com/Olical/conjure/wiki/Clojure-nREPL-CIDER-debugger https://github.com/Olical/clojure-dap