Debugging your Ruby Programs
Debugging Ruby - Techniques to Help you Fix your Code

		How often does your program do exactly what you want the first time around? Many times our programs won’t work like you expect, so we have to use the art of debugging ruby to help us finding out why.
You may be familiar with the following error message:

		
				
					
				
					
				
						undefined method 'some_method' for nil:NilClass
					
				
			
As you know, this means that a nil value managed to find it’s way into our code. Using the techniques discussed in this article you will learn how to deal with this issue and similar problems.
Understanding Errors & Stack Traces
When you are getting an error from the Ruby interpreter or your program is not doing what it should be doing then it’s time to put on your debugging hat.
If the problem is that your program is crashing, it is important to pay attention to the error message, which usually will contain clues of what’s going wrong.
Here is an example:

		
				
					
				
					
				
						def method1  method2enddef method2  puts invalid_variableendmethod1
					
				
			
Running this code will give you the following error:

		
				
					
				
					
				
						/tmp/stack.rb:6:in 'method2': undefined local variable or method 'invalid_variable' for main:Object (NameError)    from /tmp/stack.rb:2:in 'method1'    from /tmp/stack.rb:9:in '<main>'
					
				
			
This is what is known as a stack trace. Let’s analyze it together!
We start with the line on the top. This is where the actual error occurred, but it doesn’t mean the error condition originated here. However, it is still a good point to start our investigation.
Here’s the deal:



Text
Description




/tmp/stack.rb:6
File and line number


in `method2‘
Method name


undefined local variable or method ‘invalid_variable‘
Error message


main:Object
Class name


(NameError)
Exception name



As you can see the error is not that intimidating when broken down in this way. By the way, you can find a list of exceptions here.
Now:
Every line in the stack trace below the first one tells you how the code got here. It’s basically a method chain, if you keep going down you should eventually find the main method of your app.
Here is a general algorithm for dealing with a stack trace:

Read the top line of the stack trace
If the file is part of your project: open the faulting file on the indicated line number. If it isn’t, keep going down the stack trace until you find the first reference to a file you recognize
See if anything obvious jumps out to you and fix it (look for things mentioned on the error message)
If that doesn’t help then you will need to find more information, like the values of the affected variables.


The most basic (which doesn’t necessarily mean bad) debugging technique that you are probably familiar with is just dumping the values of the suspected variables.
In Ruby you can do that using puts or p. Using p is equivalent to saying puts variable.inspect, and it’s useful for looking at objects.
Example:

		
				
					
				
					
				
						Book = Struct.new(:title)def find_book(title)  books = []  books << Book.new('Eloquent Ruby')  books.find { |b| b.title == title }endbook = find_book('Eloquent Ruby')p book # This will print our book objectbook = find_book('POODR')p book # This will print nilbook.name # Guess what happens next :)
					
				
			
Digging Deeper with Pry
When you have many variables to check, adding puts everywhere might not be very practical. In that case you should try pry.
Using pry you can make your code stop at a specific line of code (also known as a breakpoint) and it will drop you into an irb-like environment, where you can evaluate ruby code in the context of your project, or execute one of the many useful pry commands.
Using pry is really easy:
All you have to do is drop binding.pry where you would like to install a pry breakpoint. You will also need to require pry into your project (require ‘pry’).
If you just want to do it temporarily then you can call your ruby script like this:

		
That won’t be very helpful for a rails app, so you may want to add pry to your Gemfile. What I like to do is to have a macro/snippet on my editor that already includes the require in the same line than the breakpoint, so when I delete it I will be deleting both things.
This is what you will see when you are dropped on a pry session:

If you want to completely quit a pry session you can type exit!, if you do a regular exit it runs your program until the next breakpoint.
The power of pry doesn’t end here. For example, you can use the ls command to see what methods and instance variables an object has access to.

Don’t forget to run the help command to get a listing of all the goodies!
Another Ruby Debugger: Byebug
Byebug can act as a pry replacement or as a gdb-like debugger for Ruby. If you want to use it for the former then you just drop byebug instead of binding.pry where you want your code to stop. One of the cons of using Byebug over pry is that it doesn’t provide syntax highlighting.
Let’s see how you can set breakpoints and debug you code inside byebug!
Usually you would call the help command, but in this case it is lacking a bit on information:

So you will have to consult the documentation. We can see how using the command break and a line number we can set our breakpoints. To get a list of breakpoints you can use info breakpoint.
Once your breakpoints are set, you can move through the program execution using the following commands:

step (advance one instruction, stepping into method calls)
next (advance one instruction, doesn’t get inside methods)
continue (run until the end or next breakpoint)

If you type enter without any command it with just repeat the last one, this is very useful when walking through your code.
When All Else Fails
Make sure to take a break when you have put a good amount of time in and can’t see the solution, when you come back with fresh eyes you will realize the solution was in front of you. You can also try explaining the problem to someone else.
Some times you are not sure where the problem is, when this happens you still have plenty of options. For example, you may want to comment blocks of code to try and isolate the issue. If the issue disappears then you can uncomment a portion of the code that you just commented. This is a very low-tech solution, but it might be exactly what you need in certain situations.
If you got this far and nothing seems to help:
It’s time to pull out the big guns. Here are some system tools that you will often find to be helpful.
One of these tools is Wireshark, which will let you inspect network traffic. If you are dealing with SSL-encrypted traffic a mitm (Man in the middle) proxy like mitmproxy might be able to help you.
You can also try curl to initiate HTTP connections from your terminal, which may help you debug invalid server responses.
Another tool that is useful to be familiar with is strace (linux only), this tool will show you all the system calls that your app is doing. You can filter for specific system calls using the -e option. A more modern alternative to strace is sysdig.

  Warning! You may want to avoid using strace in production since it severely degrades the performance of the system under test.

Finally, if you are dealing with an issue that looks like it’s coming from some external gem, an obvious step is to inspect the gem’s source code. You can use the gem open  command to open the source code on your configured editor.
Conclusion
Even if debugging isn’t the most fun activity ever, there are plenty of tools and techniques that can make it easier for you, use them to help you.
Please share this post if you enjoyed it so more ppl can learn! 😉

            	