The Poor Man’s Debugging Toolkit: Using Clojure.inspector

When debugging a problem in Robinson, I will often print out values to the log. I can try to see the values of variables at certain points during execution. Often, these values will be some subset of the game state.

I’d like print the whole game state to the log, but it’s too much data to process visually. So I find myself printing small parts of the game state trying to hone in on the right part to show the problem. It takes far too long and it’s frustrating. I have to guess and check until I find the right data.

Enter Clojure.inspector

I stumbled on Adam Bard’s Clojure.core: Batteries (almost) included writeup on useful Clojure libraries. There is a small reference to clojure.inspector in the forward that caught my eye.

Clojure.inspector is a very small namespace of just three documented functions: inspect, inspect-table, and inspect-tree. The functions all display a GUI showing data — inspect is for viewing objects, inspect-table for viewing sequences, and inspect-tree for hierarchical data.

Wait, the game state is hierarchical data!

This is perfect.

Solution

Given the right tool, all problems are trivial. Let’s add inspector as a required namespace to Robinson’s update namesapce so that we can trigger inspection when a key is press.

(ns robinson.update
  (:require 
    ...
    clojure.inspector
    ...

And then we can wire up the keyboard so that when 5 is pressed we can inspect the game state. This snippet lies in the middle of a state machine definition mentioned in this post.

...
\5 [(fn [state]
      (clojure.inspector/inspect-tree (get state :world))
    :normal
    false]
...

That’s it. It was almost too easy.

The inspector window looks like this and it’s so useful. I’ve already caught at least one bug just by examining values.
Screenshot of inspector

Use it!

Since game states are passed to almost every logic related function in Robinson, I’ll have many opportunities to apply inspect-tree during future debugging sessions and in the meantime, I can always press 5 to peek under the hood.

If you find yourself trying to cherry-pick values to print to the log, try using clojure.inspector. It’s a big bang for your coding buck.