bastibe
bastibe

Reputation: 17199

How to debug ruby code?

I run Ubuntu 10.10. I just want to debug a simple script. After spending half a day trying to figure out how that could be done I give up. What the heck am I supposed to do?

I installed ruby-dev from the Ubuntu repository
I ran sudo gem install ruby-debug and sudo gem install ruby-debug-ide

I tried a few different ways to make this work. I tried require 'ruby-debug' and then setting debugger somewhere in the code. But Ruby won't find ruby-debug.
I tried setting up vim-ruby-debugger, which will take ages to execute :Rdebugger myScript.rb and will allow me to set breakpoints, but there doesn't seem to be a way to execute my code using that debugger.
And I tried to use NetBeans which simply crashed every time I set up the project and clicked anything.

So, dear community: There must be a way to debug Ruby. Not Rails. Nothing fancy. Just some CLI script. Please help me or I lose what is left of my sanity.

Edit: the gem exec dir was not in my path. So, at least rdebug seems to work now.

Upvotes: 29

Views: 34170

Answers (11)

imapotatoe123
imapotatoe123

Reputation: 696

I like to use the following for testing

require "debug"; binding.break

Upvotes: 0

software_writer
software_writer

Reputation: 4468

To debug Ruby code, you will need two gems: pry and pry-byebug.

Here is a simple Ruby script that adds up two numbers and prints their sum. Notice the binding.pry statement at the bottom. This statement adds a breakpoint and tells Ruby to stop execution at that point. At this point, we can examine the current state, step in and out of methods, and exit or continue the execution.

require "pry"
require "pry-byebug"

class Sandbox
  def add(a, b)
    sum = a + b
    sum
  end
end

puts "Welcome to the Sandbox"

binding.pry

box = Sandbox.new
sum = box.add(3, 4)

puts "Sum = #{sum}"

If you were to run this code in the terminal, you’d see the following code. Pry pauses the program, and the terminal is waiting for your input. Notice the arrow next to the line number, which tells you exactly where the control is.

➜  sandbox (main) ✗ ruby lib/sandbox.rb
Welcome to the Sandbox

From: /../sandbox/lib/sandbox.rb:15 :

    10:
    11: puts "Welcome to the Sandbox"
    12:
    13: binding.pry
    14:
 => 15: box = Sandbox.new
    16: sum = box.add(3, 4)
    17:
    18: puts "Sum = #{sum}"

[1] pry(main)>

Type next on the terminal to go to the following line.

[1] pry(main)> next

From: /../sandbox/lib/sandbox.rb:16 :

    11: puts "Welcome to the Sandbox"
    12:
    13: binding.pry
    14:
    15: box = Sandbox.new
 => 16: sum = box.add(3, 4)
    17:
    18: puts "Sum = #{sum}"

[1] pry(main)>

Type step into the terminal to step inside the add method. Pry will take you inside the add method.

[1] pry(main)> step

From: /../sandbox/lib/sandbox.rb:6 Sandbox#add:

    5: def add(a, b)
 => 6:   sum = a + b
    7:   sum
    8: end

During debugging, you can examine the local variables by typing ls in the terminal or simply typing the variable’s name. For example, typing a shows the a variable’s value.

[1] pry(#<Sandbox>)> a
=> 3

Type up to step out of this method, which takes you up a level in the stack. I do this a lot, especially when I find myself in the framework code while debugging.

[2] pry(#<Sandbox>)> up

From: /Users/akshayk/Dev/ruby/sandbox/lib/sandbox.rb:16 :

    11: puts "Welcome to the Sandbox"
    12:
    13: binding.pry
    14:
    15: box = Sandbox.new
 => 16: sum = box.add(3, 4)
    17:
    18: puts "Sum = #{sum}"

To continue the execution until the control hits the next breakpoint, type continue. Type exit to exit debugging.

If, at any point in time, you’d like to see where you are, type @ or whereami, and pry will show you the current breakpoint. You might find this helpful when you are reading the help (by typing help in the terminal while debugging), or have cleared the terminal and want to see where you were in the execution.

That’s pretty much how you debug Ruby code. Hope that helped.

Source: How to Debug Ruby Code

Upvotes: 1

Daniel Garmoshka
Daniel Garmoshka

Reputation: 6352

There is plenty of console-based debuggers for ruby with different features, based on which you will make choice.

If you important need - is intuitive navigation (for example next moves line-by-line, stepping into blocks), and quick comprehensible documentation - this works for me the best:

https://github.com/garmoshka-mo/pry-moves


Other cool feature which I had demand - is to debug from inside of debugger. Like if I stopped in Controller's action:

def index
    list = Orders.for_user(current_user) 
=>  binding.pry
end

Now I want to understand why list is empty? - I can run debug Orders.for_user(current_user) and see what happens there

Upvotes: 0

Xiong Chiamiov
Xiong Chiamiov

Reputation: 13714

Ruby debugging has a difficult history, littered with tools that only support a specific minor version of MRI. Thankfully, for 2.0 and onward, you can use byebug.

Command-line usage is simple: run byebug <your script>. You can also edit your file and drop the byebug function call in wherever you want to launch debugging.

Upvotes: 0

the Tin Man
the Tin Man

Reputation: 160551

Ruby-debug is for 1.8+ and ruby-debug19 is for 1.9+.

ruby-debug is easy to learn and very useful. You can tell the application to run until a certain condition exists, then have it break, making it easy to locate nil values, or other conditions that occur sporadically.

From the command-line use rdebug appname and you'll end up at the debugger prompt. If you want to run to line 100 and stop you can enter c 100 and the debugger will set a temporary break-point, the program will run then stop there if it's in the execution path. Once it stops the temporary break-point will be cleared. If you always want to stop at line 100 you could do b 100 then c and the debugger will set a permanent break-point, continue, then stop when the break-point is reached. You can clear the breakpoints, set conditional ones that occur when certain conditions apply, etc. You can type n to step to the next instruction skipping over subroutine calls, or s to step into them. There are commands to display contents of variables in various ways, so read through the docs.

From inside rdebug you can drop into an IRB shell with your variables already populated so you can poke at things to see what happens. From inside either you can inspect or set values, helping with what-if adjustments. If you do that from within rdebug you can continue the program with the altered value(s) and see how it behaves.

IRB has its place, and it's great for trying things, but it's not a substitute for the debugger, just as the debugger can do some IRB-ish things, but won't replace it. Both tools are a good combination and beat the heck out of relying on print statements or dumping to a log file.


Pry has emerged as a great combination of IRB and a debugger, and is well worth investigating.

Upvotes: 19

kenorb
kenorb

Reputation: 166457

Try default Ruby Debugger either by:

ruby -r debug filename[, ...] 

Or if it's CLI script, just change its first line from:

#!/usr/bin/env ruby

to:

#!/usr/bin/env ruby -rdebug

and the script will stop on each Exception.

Or check the following script sample:

#!/usr/bin/env ruby
class Hello
   def initialize( hello )
      @hello = hello
   end
   def hello
      @hello
   end
end

salute = Hello.new( "Hello, Mac!" )
puts salute.hello

You can debug it as shown below:

# ruby -r debug hello.rb
Debug.rb
Emacs support available.

hello.rb:3:class Hello
(rdb:1) v l
  salute => nil
(rdb:1) b 10
Set breakpoint 1 at hello.rb:10
(rdb:1) c
Hello, Mac!

Source: Ruby Debugger


Alternatively use lldb/gdb. See below the simple example to print script backtrace into foreground:

echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)

Replace lldb with gdb if works better. Prefix with sudo to debug non-owned process.

Upvotes: 0

Ale
Ale

Reputation: 166

You can see the Cheat sheet running

  gem install cheat
  cheat rdebug

This will show useful commands to use rdebug.

Upvotes: 1

frankl
frankl

Reputation: 119

pry is better compared to IRB. The following are grab from its README.

Pry is a powerful alternative to the standard IRB shell for Ruby. It is written from scratch to provide a number of advanced features, including:

  • Source code browsing (including core C source with the pry-doc gem)
  • Documentation browsing
  • Live help system
  • Open methods in editors (edit-method Class#method)
  • Syntax highlighting
  • Command shell integration (start editors, run git, and rake from within Pry)
  • Gist integration
  • Navigation around state (cd, ls and friends)
  • Runtime invocation (use Pry as a developer console or debugger)
  • Exotic object support (BasicObject instances, IClasses, ...)
  • A Powerful and flexible command system
  • Ability to view and replay history

  • Many convenience commands inspired by IPython, Smalltalk and other advanced REPLs

  • A wide-range number of plugins that provide remote sessions, full debugging functionality, and more.

Pry also aims to be more than an IRB replacement; it is an attempt to bring REPL driven programming to the Ruby language. It is currently not as powerful as tools like SLIME for lisp, but that is the general direction Pry is heading.

Pry is also fairly flexible and allows significant user customization is trivial to set it to read from any object that has a readline method and write to any object that has a puts method - many other aspects of Pry are also configurable making it a good choice for implementing custom shells.

Upvotes: 11

Jeet
Jeet

Reputation: 1380

  1. In Ruby:

    ruby -rdebug myscript.rb then,

    • b : put break-point
    • and n(ext) or s(tep) and c(ontinue)
    • p(uts) for display
  2. In Rails: Launch the server with

    • script/server --debugger

      and add debugger in the code.

Upvotes: 5

david4dev
david4dev

Reputation: 4914

Use IRB. It is an interactive Ruby shell. When errors occur, it gives a trace with line numbers so that you can tell what part of your code went wrong. You can load your source files and run individual methods to see if they are working properly. IRB provides useful output - when you enter some code, it will evaluate the expression and then print the return value using .inspect.

Upvotes: 1

Daisy Sophia Hollman
Daisy Sophia Hollman

Reputation: 6296

The best debugger I've ever used for Ruby is the one built in to Netbeans. You have to install the fast ruby debugger gem from Netbeans (I'm not sure which gem it actually is, but Netbeans prompts you to do it). I find that it works much better if you switch Netbeans away from the built-in JRuby 1.4 to your system's default Ruby installation. There's also the breakpoint gem that's worth taking a look at, and using the Ruby built-in library logger from the start of your development is also helpful. Good luck!

Upvotes: 3

Related Questions