A debugger is a tool that allows us to dissect and examine our code at different stages. Typically, when we compile a program and there’s an error, it does not give any meaningful explanation about the error. In such cases, it can be hard to locate and resolve the problem.
There are two common types of errors:
A syntax error does not compile the code until we fix the syntax. With a logical error, the code compiles without any issues, but when we execute the program, it gives unexpected results.
A debugger helps us locate and fix logical errors efficiently that, in some cases, would be a nightmare to fix without a debugger.
Ruby has a debug library that lets us examine our code at every step. To use the debugger, we can run:
ruby -r debugger {.rb FileName}
Do not forget to add -r
as it will stop the debugger from executing the code at line number one and asks the user what to do.
After we start the debugger, we will be given a lot of options:
Command | Description |
---|---|
b {x} | Set a breakpoint at line number x |
wat {expression} | Set watchpoint |
b | Displays breakpoints and watchpoints |
del {x} | Delete breakpoint at line x |
disp {expression} | Displays value of expression |
undisp {x} | Undisplays the display expression at number x |
c | Continue execution |
w | Displays stackframe |
up {x} | Moves up x levels in stack frame |
down {x} | Moves down x levels in stack frame |
fin | Finish execution of current method |
q | Quit debugger |
v {g} | Displays global variables |
v {l} | Displays local variables |
v {i} {object} | Displays instance variables of object |
v {c} {object} | Displays constants of object |
m {i} {object} | Displays instance methods of object |
m {class/module} | Displays instance methods of a class/module |
n | Executes next line |
th {l} | Displays thread list |
th {c} | Displays current thread |
th {x} | Stops thread at x |
h | Help |
Here is a pretty straightforward code that takes two names and then displays the full name. Try executing it:
class FullNamedef initialize( fname, lname )@fname = fname@lname = lname@fullname = fname + " " + lnameenddef displaynameputs "My name is #{@lname}, #{@fullname}"endendmy_name = FullName.new( "Bond", "James" )my_name.displayname
Something does not feel right – the first name and the last name seem to be flipped.
Let’s try debugging the code:
The above terminal shows a sequence of commands:
-r
flag.n
) and check the local variables. It is nil
because the line has not yet been executed.We have debugged the problem now. Flipping the arguments passed to our objects gives us the correct, full name of our 007 agent.
class FullNamedef initialize( fname, lname )@fname = fname@lname = lname@fullname = fname + " " + lnameenddef displaynameputs "My name is #{@lname}, #{@fullname}"endendmy_name = FullName.new( "James", "Bond" )my_name.displayname
Free Resources