Debugging
| IO.inspect with label | |
| Require warnings | |
| IEx.pry concept | |
| Halve the code |
IO.inspect with label
When a value looks wrong, print it with a label at the exact spot of suspicion. The label tells which print produced which line when several prints are active at once.
user = fetch_user(1)
IO.inspect(user, label: "user")
Remove every inspect call once the bug is found. Prints left in committed code add noise for the next reader.
Require warnings
Compiler warnings point at real problems: unused variables, missing clauses, and stale calls. Treat them as errors so no warning survives unnoticed.
mix compile --warnings-as-errors
Run the command before committing, and keep the output clean at all times. A project with zero warnings makes each new warning loud and easy to catch.
IEx.pry concept
For a live look inside running code, pause execution with a breakpoint call. The session stops at that line and hands over an interactive prompt with local bindings in scope.
require IEx
IEx.pry()
Breakpoints need an interactive session started from the project. They are a development tool only and must never reach committed code.
Halve the code
When nothing points at the cause, narrow the area by halves. Disable one half of the suspect code and check whether the bug stays or goes.
Repeat on the half that still fails. A few rounds move the fault from a whole module to a few lines, where one labeled inspect usually closes the case.
Next: Configs
Article author: Arthur Isaev