Demystifying Debugging

Brad Newman
7 min readJun 19, 2018

--

https://sjinnovation.com/why-do-we-debug-code/

I recently completed my second week of the Software Engineering Immersive Bootcamp at Flatiron School in NYC. I assumed that the program would be filled with highs and lows, and the first two weeks definitely confirmed my assumptions. Fortunately, my first two weeks were filled with more highs than lows, and my primary sentiment toward the program has shifted from nervousness — about switching careers, learning something completely new, and not knowing what to expect, in general — to excitement. I’m excited to continue learning, face and overcome new challenges, and discover what the remainder of the program, and the future, has in store for me.

One of my favorite parts of thinking about the first two weeks of the program is realizing the progress I have made so far. When I think back to the concepts I was learning two weeks ago, I remember how difficult everything seemed. Now, those concepts almost feel second nature to me. Two weeks from now, any topics I am currently struggling with will feel the same way — at least, I hope so!

https://media.giphy.com/media/CPskAi4C6WLHa/giphy.gif

I have quite a few takeaways from the beginning of the bootcamp, but there is one lesson that I feel is key for programming beginners: the importance of debugging throughout the code-writing process. Any time you are writing new code, there can, and likely will, be errors. Debugging throughout the writing process can save you a headache once it’s time to run your program. I’ve outlined some beginner-friendly tips and methods for debugging your Ruby code.

Error Messages Are Your Friends

This is difficult logic for most people to accept. To many people, an error message is something that just points out a failure; either the computer made a mistake — which is never the case — or we, the users, made a mistake — which is always the case, the computer is just following instructions.

https://me.me/i/im-the-last-person-would-have-suspected-but-it-was-14683828

Error messages can also seem confusing at first, especially to beginners. The reality is, error messages in Ruby are actually just trying to help. Error messages have three main parts: the location of the error; the description of the error; and the type of the error.

The location of the error includes the file name and line number where the error occurred as well as the scope of the error. These location indicators should help to direct you to the exact location of your error, or at least to the file you should examine to get a better sense of the error message.

The description of the error is the Ruby interpreter’s best guess at what went wrong. More often than not, the description of the error is specific enough to lead you to a resolution. For example, an error description that states “undefined local variable or method ‘some_word_or_phrase’ for main:Object” will likely lead you to find that you either didn’t define that word or phrase as a variable or method, or you didn’t spell the word or phrase correctly somewhere in your code.

https://media.giphy.com/media/55offP4umeJUAvWwHP/giphy.gif

There are many different error types, but two of the most common are Name Errors and Syntax Errors. If the Ruby interpreter comes across a word it doesn’t recognize, it will assume it is a variable or a method. If that variable or method was never defined in your code, you will be given a Name Error (like the one in the example above). A Syntax Error is given when incorrect syntax is used somewhere in the code. Most likely, you are missing an “end” keyword somewhere in your code, but either way, the Ruby interpreter will try to direct you to the error as best it can.

Find Your Place With P and Puts

If you receive an error message after running your program, but find it difficult to locate the error(s) using the information from the message, try placing “p” or “puts” throughout your code. These methods are used to output the values of suspected variables, or even to just output some kind of message, at different points of your program. For example, if you place “puts ‘I am working.’” within your code, and this phrase is displayed on your terminal before you receive an error message, you know your code is working up until this point without an error.

https://media.giphy.com/media/dIxkmtCuuBQuM9Ux1E/giphy.gif

Using “p” instead of “puts” can be even more helpful when debugging your program. Because “puts” calls “to_s” (to string) on an object, you can’t be exactly sure what the class of the object is. With “p”, you are calling “inspect” on the object, so you have a better idea of what you are actually looking at once this result is displayed on the terminal.

With “p”, you know you are looking at an array.

While “p” and “puts” are very useful if you are trying to identify the exact point at which your program is “breaking”, they are not the best tools for testing the output of suspected variables and methods when you have many variables and methods to test. This leads me to the next, and probably most important, tool for debugging during the code-writing process.

In Pry We Trust

Pry is a ruby gem that allows you to freeze your code and enter an environment similar to IRB where you can test your suspected variables and methods. The basic premise of using pry is simple. Just call “require ‘pry’” at the beginning of your program and place “binding.pry” somewhere within the body of the code you would like to test. Don’t forget to call the method you are testing somewhere in your program, otherwise your program will run through without hitting the binding.pry!

https://media.giphy.com/media/l2YWkNuHdyTS3nCgg/giphy.gif

Once you run your program, you will enter the pry session in your command line. Here, you can call on different methods and variables to confirm that the output you receive is exactly what you were expecting. Binding.pry is especially useful while you are writing your code. Rather than assuming each variable or method is going to give the exact output you are expecting, you can actually test those assumptions right away.

If you are looking to test your program as a whole, rather than testing individual methods within the program, you can simply place “Pry.start” at the end of the file you are running. Again, as long as you have called all of the variables and methods you would like to test somewhere within your program, Pry.start will drop you into a pry session where you can evaluate and test your code.

To return to your command line from a pry session, simply type “exit!” into the pry session and hit “enter”.

https://media.giphy.com/media/11j6oiwfuzwu9G/giphy.gif

Final Thoughts

Learning to code is challenging, and often times stressful, but you can make it easier on yourself by understanding the tools available to you when it comes to testing and debugging your projects.

Don’t view error messages as failure notices. This will lead to added stress and frustration. Instead, read what the error message is telling you and let it guide you to a solution. If you are still struggling to locate the source of your error, use “p” and “puts” throughout your code to help determine the exact point at which your program is “breaking”.

Try not to make assumptions when you have tools available to you to test those assumptions. If you are hoping that a method will give you a certain result, drop a “binding.pry” within that method and find out if your assumptions are correct. You can save yourself a lot of time and confusion by getting into the habit of testing and debugging your code while you are writing it.

https://media.giphy.com/media/bWM2eWYfN3r20/giphy.gif

Finally, be patient with yourself. When you are a beginner learning to code, most of the concepts will be completely new and the process will seem overwhelming at times. But the challenges you will face are what make the process fun. Eventually, those challenges will turn into rewarding victories, which will give you a great sense of accomplishment. Then, you can move onto another challenge feeling a little more prepared to handle it than the last.

--

--