I copied the following Ruby code from the Internet and made a few changes.
#insert code here
But it doesn't work!
Please help. What can I do to debug the program by myself?
I copied the following Ruby code from the Internet and made a few changes.
#insert code here
But it doesn't work!
Please help. What can I do to debug the program by myself?
The mother of all debugger is plain old print screen. Most of the time, you probably only want to inspect some simple objects, a quick and easy way is like this:
This will print out the contents of @result to STDOUT with a line in front for easy identification.
Bonus if you use a autoload / reload capable framework like Rails, you won't even need to restart your app. (Unless the code you are debugging is not reloaded due to framework specific settings)
I find this works for 90% of the use case for me. You can also use ruby-debug, but I find it overkill most of the time.
Debugging by raising exceptions is far easier than squinting through
print
log statements, and for most bugs, its generally much faster than opening up an irb debugger likepry
orbyebug
. Those tools should not be your first step.Debugging Ruby/Rails Quickly:
1. Fast Method: Raise an
Exception
then and.inspect
its resultThe fastest way to debug Ruby (especially Rails) code is to
raise
an exception along the execution path of your code while calling.inspect
on the method or object (e.g.foo
):In the above code,
raise
triggers anException
that halts execution of your code, and returns an error message that conveniently contains.inspect
information about the object/method (i.e.foo
) on the line that you're trying to debug.This technique is useful for quickly examining an object or method (e.g. is it
nil
?) and for immediately confirming whether a line of code is even getting executed at all within a given context.2. Fallback: Use a ruby IRB debugger like
byebug
orpry
Only after you have information about the state of your codes execution flow should you consider moving to a ruby gem irb debugger like
pry
orbyebug
where you can delve more deeply into the state of objects within your execution path.General Beginner Advice
When you are trying to debug a problem, good advice is to always: Read The !@#$ing Error Message (RTFM)
That means reading error messages carefully and completely before acting so that you understand what it's trying to tell you. When you debug, ask the following mental questions, in this order, when reading an error message:
nil
?)In the stack trace pay particular attention to lines of code that come from your project (e.g. lines starting with
app/...
if you are using Rails). 99% of the time the problem is with your own code.To illustrate why interpreting in this order is important...
E.g. a Ruby error message that confuses many beginners:
You execute code that at some point executes as such:
and you get an error that states:
undefined method "bar" for Nil:nilClass
Beginners see this error and think the problem is that the method
bar
is undefined. It's not. In this error the real part that matters is:for Nil:nilClass
for Nil:nilClass
means that@foo
is Nil!@foo
is not aFoo
instance variable! You have an object that isNil
. When you see this error, it's simply ruby trying to tell you that the methodbar
doesn't exist for objects of the classNil
. (well duh! since we are trying to use a method for an object of the classFoo
notNil
).Unfortunately, due to how this error is written (
undefined method "bar" for Nil:nilClass
) its easy to get tricked into thinking this error has to do withbar
beingundefined
. When not read carefully this error causes beginners to mistakenly go digging into the details of thebar
method onFoo
, entirely missing the part of the error that hints that the object is of the wrong class (in this case: nil). It's a mistake that's easily avoided by reading error messages in their entirety.Summary:
Always carefully read the entire error message before beginning any debugging. That means: Always check the class type of an object in an error message first, then its methods, before you begin sleuthing into any stacktrace or line of code where you think the error may be occurring. Those 5 seconds can save you 5 hours of frustration.
tl;dr: Don't squint at print logs: raise exceptions instead. Avoid rabbit holes by reading errors carefully before debugging.
As banister recommended: use pry! I can only agree on this.
pry is a much better repl than irb.
You need to add
to your source file and then insert a breakpoint in your source code by adding
at the place where you want to have a look at the things (this is like triggering a breakpoint in a classic IDE environment)
Once your program hits the
line, you'll be thrown right into the pry repl, with all the context of your program right at hand, so that you can simply explore everything around, investigate all objects, change state, and even change code on the fly.
I believe you can not change the code of the method that you are currently in, so you can sadly not change the next line to be executed. But good ruby code tends to be single line anyway ;-)
printf debugging
There has always been a controversy around debugging techniques, some people like to debug by print statements, some other ones like to dig deep with a debugger.
I'd suggest that you try both approaches.
Actually one of the old Unix men recently said, that printf debugging was a faster way to go for him at some points.
But if you are new at some job and need to understand a big blob of code, then it's really usefull to step throughout there, putting some breakpoints here and there, going along with it how it works.
It should give you some understanding how the code is weaved.
If you are new to some other peoples software, It might help you to step through there.
You'll quickly find out if they arranged it in a clever way, or if that's just a bunch of shit.
Use Pry (GitHub).
Install via:
Then add:
into your program.
Well, ruby standard lib has an easy to use gdb-like console debugger: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html No need to install any extra gems. Rails scripts can be debugged that way too.
e.g.