I've been coding in Ruby/Rails for almost 9 months now, having spent years before that in Python.
While I'm really enjoying Rails, there's one area where I often find myself frustrated: chasing down stubborn bugs. In other languages I can almost always track down difficulties without too much trouble, but when I hit a wall debugging rails, I tend to really hit a wall. I guess what I'm asking is: what strategies do advanced rails users employ to track down more stubborn errors?
At the moment my approach is usually:
Examine the stack trace (most simple bugs solved here)
Run debugger/pry/console & examine the environment, pace through each step if necessary
Google it
Post on stack overflow/github issues
Procrastinate and/or swear profusely
If any advanced rails-ers would share their strategy for chasing down more stubborn bugs, I'd be really appreciative. In short, what do yo do when trace/debugger don't offer any clues?
I personally find that firing up the rails console and stepping through things there manually helps sort out most "hard to track down" bugs. However, lately I started using pry and adding "binding.pry" calls into code that I want to debug. It seems the trick is to figure out where to place the binding.pry call. Invaluable in view code as well as complicated test code that you inherited.
Being with Rails mere 5 years, I do not consider myself an advanced Railser, but nevertheless I'll happily share my knowledge. :-)
The main thing when dealing with any (except some very, very trivial ones) is to write a test for this bug.
A few times it happened that I solved the bug at this stage - for example when the bug was related to the automatic class reloading, which is active in development, and turned off in test mode.
Then I usually just place some logger.debug
statements with a lot of inspect
and caller(0).join("\n\t")
in it. Then I very carefully examine the log file.
Because the 'test.log' can have a few hundreds megabytes, I always remember to zero it before I run my test. Also I usually run just one test method at the time, because the output would be unreadable otherwise.
I do not use a dedicated debugger. In some old version of ruby the debugger stopped working, I learned to live without it, and never looked back.
A few utilities which may be useful:
A function defined in my ~/.bashrc
, which lets me to invoke a single test method (or a group of methods):
$ testuj test/unit/user_test.rb -n test_name_validations
$ testuj test/unit/user_test.rb -n /_name_/
function testuj () {
if [ -n "${BUNDLE_GEMFILE}" ]
then
# This is a Rails3 project - it is run by `bundle exec`
ruby -I"lib:test" "$@"
else
# This is a Rails1 project. No bundler.
ruby -e 'ARGV.each { |f| load f unless f =~ /^-/ ; break if f == "-n" }' "$@"
fi
}
And this method helps me with logging and checking the timing of some steps:
Object.module_eval do
def czekpoint(note = nil)
n = Time.now
$czekpoint_previous ||= n
$czekpoint_number ||= 0
$czekpoint_number += 1
t = n - $czekpoint_previous
msg = "CZEKPOINT: %2d %8.6f %s %s" % [$czekpoint_number, t, caller.first.to_s.in_yellow, note.to_s.in_red]
Rails.logger.debug msg # In older Rails it was RAILS_DEFAULT_LOGGER
STDERR.puts msg
$czekpoint_previous = n
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With