We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Debugging Elixir
Elixir provides a couple of tools to make debugging a breeze. In this blog post, we’ll focus on three built-in debugging methods in Elixir: IO.inspect
, dbg
, and tap
.
IO.inspect
The IO.inspect/2
function is a simple yet powerful tool for debugging. It returns the value it was given, making it easy to insert into your code without altering behavior. It also prints the value to the standard output, which can be customized.
Example Scenario: Use IO.inspect
when you want a quick and dirty way to see what a variable or expression evaluates to without affecting the existing code flow.
iex(2)> list = [1, 2, 3]
iex(3)> new_list = Enum.map(list, fn x -> IO.inspect(x) * 2 end)
1
2
3
[2, 4, 6]
IO.inspect/2
also accepts a label
option to make it easy to search through terminal output.
iex(1)> IO.inspect obscure_map, label: "What is in this map?"
What is in this map?: %{key: "value"}
Now you can search backwards for the label phrase - I like to use labeling for seeing how data looks in a before and after state:
my_map
|> IO.inspect(label: "Before")
|> transform_map()
|> IO.inspect(label: "After")
Before: %{key: "value"}
After: %{key: "value", new_key: "new value"}
dbg
The dbg/2
function allows you to inspect the value returned by a function or a pipeline of functions. It is especially useful for debugging pipelines, as it prints the value at each step of the pipeline before it.
Example Scenario: Use dbg
when you want to understand how data transforms at each stage of a pipeline.
"Elixir is cool!"
|> String.trim_trailing("!")
|> String.split()
|> List.first()
|> dbg()
This will output:
"Elixir is cool!" => "Elixir is cool!"
|> String.trim_trailing("!") => "Elixir is cool"
|> String.split() => ["Elixir", "is", "cool"]
|> List.first() => "Elixir"
tap
The tap/2
function is similar to IO.inspect
but allows you to pass a function that will receive the value for further actions, such as logging or computation.
Example Scenario: Use tap
when you want to perform some side-effect operation on the value, like logging or sending it to a monitoring service.
value
|> do_something()
|> tap(&send_to_monitoring(&1))
|> do_something_else()
Conclusion
Elixir provides a range of debugging tools, each with its own strengths. IO.inspect
is great for quick inspections, dbg
excels in pipeline debugging, and tap
is useful for side-effects. Choose the one that fits your debugging needs.
Build an AI Powered Instagram Clone with LiveView is on sale now!