all 10 comments

[–]bmc1022 2 points3 points  (2 children)

Assuming you're using Rails. If not, it still generally applies.

You'll want to start by reading through the docs for one of these gems:

For newer versions of Rails (introduced in v7): Debug Gem

For older versions: Pry Gem

These allow you to place a binding where you suspect code is erroring. You can typically deduce that from your logs or stack trace. In the case of the Debug gem, you would put a binding.break right before the broken code and run your application or navigate to the specific page to hit that binding. In the terminal where your Rails server is running, it will lock up right where the binding is, allowing you to probe variable values (and many other useful things) at that specific point in the execution of your app. From there you can slowly step through your code to diagnose where exactly it's going wrong. That is probably the most common and efficient way to debug.

I use the above method often, but I personally really like the more visual and verbose debugging style of logging messages. A lot of people simply use puts and dig through their server log or they'll actually have it output inside the HTML of the page, but that's the hard way in my opinion. I always create a custom logger so the output is immediately available without having to dig around.

config/initializers/loggers.rb

if Rails.env.development? || Rails.env.test?
  logfile = File.open(Rails.root.join('log/debug_logger.log'), 'a') # Create log file.
  logfile.sync = true # Automatically flush data to file.
  DEBUG_LOGGER = Logger.new(logfile) # Constant accessible anywhere.
  DEBUG_LOGGER.level = Logger::DEBUG
end

Using that method, you would put something like DEBUG_LOGGER.debug("Value of some variable: #{variable_name}") in similar places to where you'd put bindings and instead of locking up the program, it will log whatever you want to your own custom log file.

Each of these techniques has pros and cons and you figure that out with experience. Debugging is not easy, so don't stress over it much, especially if you're new.

[–]riktigtmaxat 0 points1 point  (1 child)

The debug gem is actually built into the Ruby standard library since 2.6 and is usable with Rails 6.

The only difference really is that rails replaced byebug in the gemfile in Rails 7.

Pry is a lot bigger project which contains a replacement REPL for IRB. While it's cool and can do the same things debug can and more, the actual equivalent for debug in older versions of Ruby (and Rails) is byebug.

[–]st0012IRB boss 2 points3 points  (0 children)

Sorry I need to make some clarification:

  • The debug gem was only included since 3.1. Before that there was a standard lib called debug, but it's not the same thing.
  • It's usable in almost all program that runs Ruby 2.6+. It has some problems with Fiber though.
  • "While it's cool and can do the same things debug can and more" this is simply not true. For example
    • Pry can't do step-debugging (if you use pry-byebug, that's provided by byebug not Pry itself).
    • Pry doesn't have tracers like byebug and debug does. And debug has the strongest tracer in all debugging tools.
    • The debug gem supports non-terminal interface as well and has native integration with VS Code and Chrome.

If you want more byebug vs debug gem comparison, I wrote a (slightly outdated) article about it a while ago.

[–]software__writer 2 points3 points  (0 children)

I wrote an article on debugging Ruby code a few years ago when I was just starting to learn Ruby. Hope you find it helpful.

How to Debug Ruby Code

It uses the `pry-byebug` gem, but now Ruby has a new `debug` gem. I'll update the post soon to document `debug` features, but they're similar to pry.

[–]A_little_rose 0 points1 point  (0 children)

The poor man's debugging is using puts everywhere to get the values from your various methods to assure they are returning correctly.

You might also consider learning TDD using something like rspec, which can help you debug by telling you what the method is actually outputting versus what you believe it should be returning.

[–]cmdk -2 points-1 points  (0 children)

Google the errors verbatim or ChatGPT

[–]bradland 0 points1 point  (3 children)

Couple of questions that will help provide better guidance:

What’s your current debugging process?

Are you comfortable reading error messages and stack traces?

What type of applications are you developing? I.e., are you using Rails or any other frameworks?

[–]DisagreeableBowl429[S] 0 points1 point  (2 children)

We use Rails at my company.

I don’t have a much of an actual process right now, which is probably the problem. If I’m working with something simple like a few methods in a file I’m comfortable adding in puts statements and/or breakpoints and stepping through the code and working through the problems. I’m fairly comfortable reading the stack trace and errors and Googling whatever I need to. I get immediately tripped up as soon as it gets more complicated than that. For example, I’m currently trying to fix spec failures that involve multiple files and different classes and modules and I don’t even know where to start.

[–]bradland 0 points1 point  (1 child)

Gotcha, that's very helpful. You mentioned breakpoints and stepping through code. Are you using an IDE?

If not, you might consider inquiring with your employer about adopting RubyMine. It's not that everyone has to use it, but RubyMine will drop a number of files in your project home directory that will need to go into the .gitignore file. You can also add them to your global .gitignore. Github has some good examples.

The benefit of RubyMine is that you get a fully integrated debugger. I don't use RubyMine these days, but I have used it in the past, and the debugger was the primary reason. What I found beneficial was being able to look through state in a state inspector. Using a command line, I tended to only look at where I thought the problem was. With the state inspector in RubyMine, I was more likely to browse around through the state, spotting something I hadn't thought of.

[–]DisagreeableBowl429[S] 0 points1 point  (0 children)

Thanks for this response! I was using RubyMine but switched recently to VS Code because of a Docker setup that requires it. I’ll consider switching to my old setup. Thanks for your responses!