Monday, January 28, 2013

A little weird, but interesting: using IntelliJ LeClojure's debugger with Clojure code

I have been working on a web app using Compojure, Noir, and Hiccup. I usually run both lein repl and lein run concurrently and use either IntelliJ or Aquamacs (Mac Emacs) as a code editor. If I am working on a small bit of new code and experimenting a lot, then Aquamacs + nrepl works well for me. If I have my MacBook Air plugged into a huge monitor sometimes I run lein run and a LeClojure repl inside IntelliJ and detach a few edit panes as separate windows - so many nice choices for development!

I don't really like debuggers because getting into the habit of using them can end up wasting a lot of time that could be spent writing unit tests, etc. That said, I was looking at some Ruby code I wrote for a customer but have not deployed and it occurred to me to try the RubyMine debugger which worked very well and generally didn't get in my way or waste too much time manually stepping through some code.

So, I decided to spend a little time trying IntelliJ LeClojure's debugger on my Clojure project:

I wrote a little stub file to run as the debug target "script":

(ns cookingspace)
(use 'cookingspace)
(-main)
I placed this file in the top level project directory so the relative path for loading required data files is set up OK. Also, I had to change the default run/debug option to not make the project before running - this is necessary since I have top level expressions that initialize data from reading data files, and the Clojure compiler is not run from the project directory so I would get build errors. You probably will not have that issue with your projects.

One thing that is cool about running the app in the debugger is that the LeClojure plugin also starts a repl (see the second tab at the bottom to the screenshot) that shows all debug println print outs and provides a repl without having to start a separate process.

I don't think that I will use the debugger very often (again, using a debugger to understand and debug code is usually not the best use of time) but it is cool to have another tool. That said, I might find that always running in the debugger and only setting breakpoints on the rare occasions that I need to better understand what some code is doing might work well. I will try this mode of development for a few hours a week as an experiment.

2 comments:

Dax said...

Can you set breakpoints running a compojure app created in lein2? I create a Leiningen config, set the working directory to the app root, set goals as "ring server". "Run" works fine, but "Debug" doesn't even seem to kick off a process at all, much less stop at breakpoints.

Mark Watson, author and consultant said...

Hello Dax, I was unable to run the debugger with lien. For debugging the web app, as per my blog article, I wrote a little stub file to run as the debug target "script" and run/debug this with a right mouse click on this file.

To debug non-UI code, I wrote a little stub dev.clj with a function "load" that uses all required name spaces with :reload-all set. I right click on dev.clj in the file browser in IntelliJ to debug this.

I hope that helps!