This blog post was originally published here
The most basic debugging tool is a print statement. It could be print
function, echo
, console.log
, or alert
. Principle is the same: you display (partial) state of the program on the screen, check what stands out, and try to diagnose the issue. “It seems the loop is running more than it should. Let’s see what’s the value of i
here”.
No manual is needed to teach it. The idea just comes naturally to programmers.
It works wonderfully for a while. But as programmers get more experienced, they discover better tools called debuggers, which allow programmers to add breakpoints and watchers. With breakpoints, the programmer can pause the execution of program at a specific point and inspect the state with a greater flexibility. In case of watchers, they can keep an eye on the state of a variable.
I have used these tools, too. Over the years, however, I have realized that except for very specific situations, “Print” just works better.
- Print is universal: Every language has it. After all, putting something on screen is a pretty fundamental feature of any language. Debuggers can vary across different languages/platforms.
-
Print doesn’t need specialized tools:
print
is part of the code. Setting up debugger can often be a hassle, since the debugger and the program are usually different. Sometimes, the integration is seamless, like Chrome DevTools, but with something like node.js, it’s not as easy to make the setup work. - Print doesn’t tie you to a particular tool: Let’s say you’ve the setup working in VS Code. What if you want to switch your editor? You’ll have to figure out to make it work in that editor too. Print, on the other hand, will work everywhere.
- Print is faster to use: Compared to creating multiple breakpoints and watchers, and removing them after use, print is definitely easier. Sure breakpoints give you more flexibility in diagnosing the issue, but often most issues aren’t that complicated to warrant them.
- Print works on Staging and Production: It’s not easy to work with debug tools when you’re dealing with code running on the server. On the other hand, print statements work there too. Even if you don’t have access to STDOUT, you can write statements to a file or send them to a logging server/service (e.g, Loggly).
- Minifying/Compiling code doesn’t break print: If you’re compiling/minified your code, there’s extra complexity in mapping original source do to the compiled one. Let’s say you encounter an issue in the final build. With minified variable and function names, it would be exhausting to find the root cause. However, if your original source includes a print statement, it would be compiled as well and the variables you’re interested in will be displayed.
Print statements are powerful, versatile and flexible. They are rudimentary but every time I have tried to upgrade myself to supposedly better tools, I have come back to printing variables. They are “it just works” version of debugging.
Debuggers have their place. They are useful in places where you don't have the liberty to modify the code or you want to analyse the execution stack better. But in day-to-day work, you'll find print to be a better solution.
Top comments (7)
I would have written might be the only debug tool you need..
As you said
print
is great as it's universal but just like withdump and die
you hit their limitation quickly.It's very important to know how to use a proper debugger and set up should not be a reason for preferring
print
over a full blown debugger.People in my team use either PhpStorm or VS Code and setting up the debugger on either is just a matter of changing a Docker environment variable.
It's worth "wasting" time setting up your dev env at the beginning because you'll end up saving hours down the line when working on complex bugs.
In my day-to-day work I rarely use print or print to file. I just hit F12 in PhpStorm and debugger is ready.
Of course I still occasionally throw "print to file" statements on production when something is acting weird but if it gets too complicated then I just pull some data locally and use a debugger.
Your article offers an interesting point of view but listing cons of using print statements would be a nice addition.
👋
You're right! I think people should give them a try, at least. Maybe they will work better.
I work on multiple projects, and the biggest problem I encountered was making sure debuggers work reliably in every project. Sometimes I found the debugger process isn't running and sometimes VS code had problem binding to the process. But maybe I can give them another try.
I took time to set up a Docker environment that works for all the PHP projects I work on. It is very enjoyable to know it’s plug and play (and debug). :)
What tech are you using?
yo I honestly did not use debug tools except for print and log, but man does it make a difference. I changed recently (colleague taught me to use it and install) It really changed the game for me utilizing the php, xdebug is so good.
And when you start playing with xdebug’s profiler you’re going to love finding bottlenecks and optimize your scripts!
😯
Printing seems easier at first, because it’s so intuitive and doesn’t have much of a learning curve.
Debugging on the other hand requires you to invest a little bit of time beforehand to set everything up, but after that it’s fairly easy. Most languages I know come with a debugger. Debugging tends to work in roughly similar ways across different tools, especially if those tools are part of the same family (e.g. JetBrains IDEs), so it’s not that different from having to look up what command you need to print things. And as an added bonus you no longer run the risk of getting “You forgot to remove this print/log statement” comments in pull requests. 🙃
Having said that, I still use print statements from time to time, but only when writing tiny unit tests and languages that I rarely use.