In Ruby, how do binding.pry, pry-byebug and byebug relate to the debug gem, and which would you pick for a new Ruby 4.0 project?
answer
- Pry is a REPL, not a stepper
- pry-byebug adds stepping to Pry
- byebug: C extension on TracePoint
- debug gem bundled since 3.1
- remote attach only in debug
basics
~20 sbinding.pry opens Pry, a richer console with no stepping; pry-byebug adds byebug's stepping to it; byebug is a standalone C-extension debugger. For a new Ruby 4.0 project the default is the debug gem, bundled with Ruby, with stepping, remote attach and editor integration.
solid answer
~40 s**Pry** (0.16 supports Ruby 4.0) is an alternative REPL: `binding.pry` opens it in the current scope with commands like `whereami` (`@`), `show-source` (`$`), `ls`, `cd`, `exit` to continue, `exit-program` (`!!!`) and `disable-pry`. On its own it cannot step. **byebug** is a debugger built as a C extension on the TracePoint and debug-inspector APIs; you call `byebug` in code and get `next`, `step`, `finish`, `continue`, `break` and `where`/`bt`. Version 13 needs Ruby 3.2 or later. **pry-byebug** glues them together so a `binding.pry` session gains byebug's stepping. The **debug gem** is Ruby's own debugger, bundled since 3.1: `binding.break`, `rdbg`, `catch`, remote attach and a VS Code/Chrome protocol. For a new project it is the default choice; Pry stays attractive as a console, and teams that already use it can keep it.
code
ruby · 6 lines# Gemfile
group :development, :test do
gem "debug" # binding.break, rdbg
# gem "pry" # only if the team wants Pry's console
# gem "pry-byebug" # adds byebug stepping to binding.pry
endgo deeper
Know that binding.pry opens a console, byebug and the debug gem can step, and the debug gem ships with Ruby.
Explain REPL versus debugger, why pry-byebug exists, and how commands map between byebug and the debug gem.
Recommend the debug gem for new code on its bundled status, remote attach and editor protocol, and plan a low-friction migration off byebug.
Standardise one debugging stack across teams and CI images, weighing familiarity with Pry against the maintenance cost of extra native gems.
## Four tools, two jobs Ruby's debugging tools do one or both of two jobs: - a **REPL** at a paused point — look around, evaluate expressions, read source; - a **debugger** — control execution: step, finish, break on lines, methods and exceptions. | Tool | Entry point | Job | Notes | |---|---|---|---| | Pry | `binding.pry` | REPL | rich commands, no stepping on its own | | byebug | `byebug` in code | debugger | C extension on TracePoint; needs Ruby 3.2+ in v13 | | pry-byebug | `binding.pry` | both | adds byebug's stepping to a Pry session | | debug gem | `binding.break`, `debugger`, `rdbg` | both | bundled with Ruby since 3.1; remote and editor protocols | ## Pry Pry is a replacement for IRB with its own command system. After `binding.pry` you get commands such as: - `whereami` (alias `@`) — the code around the current line; - `show-source` (aliases `$`, `show-method`) and `show-doc` (`?`); - `ls` and `cd` to list and enter objects; - `wtf?` — the backtrace of the most recent exception; - `exit` to leave the session and let the program continue, `exit-program` (aliases `!!!`, `quit-program`) to end the program, and `disable-pry` to skip every later `binding.pry`. Pry 0.16 (December 2025) added Ruby 4.0 support and requires and defaults to Reline on newer Rubies. It does not move execution forward by itself. ## byebug and pry-byebug **byebug** controls execution through the **TracePoint API** and inspects the stack through the **debug inspector API**, implemented as a C extension for speed. Put `byebug` in a method and you get a `(byebug)` prompt with `next`, `step`, `finish`, `continue`, `break`, `where` (aliases `bt`, `backtrace`), `info` and more. Version 13.0 (January 2026) dropped Ruby 3.1 and was updated for Ruby 4.0. **pry-byebug** is a separate gem that wires byebug's stepping into Pry, so one `binding.pry` gives you Pry's console and byebug's execution control. ## The debug gem The **debug gem** is maintained with Ruby itself and is bundled from 3.1 onwards: - entry points `binding.break` / `binding.b` / `debugger` after `require "debug"`, or no code change at all with `rdbg` and `rdbg -c`; - `step`, `next`, `finish`, `continue`, `break` with `if:`, `catch` for exceptions, `watch`; - **remote debugging** over a UNIX socket or TCP (`rdbg --open`, `rdbg -A`), which the others do not offer out of the box; - a debug adapter used by VS Code and a Chrome DevTools integration; - IRB integration in both directions: IRB's `debug` command upgrades a `binding.irb` session, and `RUBY_DEBUG_IRB_CONSOLE=1` uses IRB as the debugger's console. ## Choosing for a new Ruby 4.0 project 1. **Default to the debug gem.** It ships with Ruby, needs only `gem "debug"` in the development group, and covers stepping, exception breakpoints, remote attach and editors. 2. **Add Pry if the team wants its console**, knowing stepping then comes from pry-byebug or from the debug gem separately. 3. **Keep byebug where it already works**, but it is an extra native dependency with its own compatibility window. 4. **Do not mix entry points casually**: a `binding.pry` left in code does nothing useful if Pry is not in the bundle. ## Migrating habits - `binding.pry` → `binding.break`; `whereami` exists in both. - `next`, `step`, `finish`, `continue` mean the same in byebug and the debug gem. - byebug's `where` → the debug gem's `bt`, which byebug also accepts.
- At a binding.pry prompt without pry-byebug, you type next. What happens?Plain Pry has no stepping commands, so `next` is not a Pry command and is passed to Ruby, which rejects a bare `next` there with an error instead of stepping. Stepping requires pry-byebug (or switching to the debug gem's `binding.break`).
- Which of these tools can attach to a process that has no terminal?The debug gem: `rdbg --open` (or `require "debug/open"`) makes the process listen on a UNIX socket or TCP port and `rdbg -A` attaches a console. Pry, byebug and pry-byebug need the paused program's own terminal in their standard setup.
- How do you leave a binding.pry session so the program keeps running, versus ending it?`exit` leaves the session and the program continues from the breakpoint; `exit-program` (alias `!!!`) ends the program. `disable-pry` stops all later `binding.pry` calls and exits the current session.
saying these in an interview costs you the question
- binding.pry can step through code without any extra gem.
- The debug gem must be downloaded separately before Ruby 4.0 can use it.
- byebug and pry-byebug are the only debuggers that run on Ruby 4.0.
- exit in a binding.pry session always terminates the program.
- The debug gem cannot use IRB as its console.