Inspector, a better way to debug Elixir Code

marciol

Marcio Lopes de Faria

Posted on September 17, 2021

Inspector, a better way to debug Elixir Code

EDIT: Since Elixir 1.14, there is a new macro dbg/2 that substitute the Inspector package.

I have been tinkering with better ways to improve my Elixir workflow and during this journey I realized that I am, somehow, trying to bring things which I'm used with from other environments, the same way a foreign citizen does when living in a different country.

Elixir prizes highly the Developer Experience, so that we have the astounding tools to generate documentation, first quality package management, and an excellent and mature build tool, and a REPL, iex that allows fast experiments, but I think that may I have pushed a lot the expected usage of it, in a not intended way as it was planned by the creators.

We can feel it during a IEx.pry/0 usage, it's a pretty limited tool, if you are accustomed to use Ruby pry for example, but given that Elixir doesn't hold mutable state, maybe it isn't necessary at all, so I started to think about the root cause of my dissatisfaction and I found it.

Debugging

Elixir is blaze fast, and we can notice it clearly when running a test suite with a lot of tests, they run really fast and the maintainers are working hard to make it even faster, so the so called Puts debugging is more than enough.

But what really hurts is to type always and everyplace the same think, IO.inspect/2, passing ad-hoc variables. It's not uncommon to make several calls to IO.inspect/2 during a debugging session, so if we improve it, enhancing the IO.inspect/2?

This is how Inspector was born, a library that makes debugging less annoying. You need only to place it in the calling site, like this:

# If this code is on lib/my_module.ex
defmodule MyModule do
  def my_function(args) do
    awesome_var = :foo
    amazing_var = :bar
    require Inspector; Inspector.i
  end
end

MyModule.my_function(:hey)
Enter fullscreen mode Exit fullscreen mode

And you will see in the stdout:

inspector: %{
  bindings: [
    args: :hey,
    awesome_var: :foo,
    amazing_var: :bar
  ],
  file: "lib/my_module.ex:5",
  location: "MyModule.my_function/1"
}
Enter fullscreen mode Exit fullscreen mode

If you uses Vim or Neovim, like me, you can even make it better with a key-map:

nnoremap <Leader>i orequire Inspector; Inspector.i<esc>
Enter fullscreen mode Exit fullscreen mode

I hight recommend use it running this simple command:

Or with mix test.watch found here

That is it folks. Happy debugging!

💖 💪 🙅 🚩
marciol
Marcio Lopes de Faria

Posted on September 17, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related