skip to content

Inside an IRB session opened by binding.irb, what does IRB's debug command do, and when does it refuse to start?

level: middleimportance: should knowfreq 30%

answer

  1. prompt becomes irb:rdbg
  2. hands control to the debug gem
  3. only from a binding.irb session
  4. next, step, break start it too
  5. no remote attach, no _

basics

~20 s

IRB's debug command hands the paused binding.irb session to the debug gem: the prompt becomes irb:rdbg and commands like next and step work beside IRB's own. It refuses outside binding.irb, in multi-irb mode, or without a loadable debug gem.

solid answer

~40 s

At a `binding.irb` prompt, `debug` (or `irb_debug` if the scope already defines a `debug` method) loads the debug gem, attaches it to the current session and changes the prompt from `irb` to `irb:rdbg`. From then on the debug gem's commands work at that prompt while IRB's `show_source`, `ls`, `$` and `@`, multiline input and completion remain available. Typing `next`, `step`, `break`, `continue` or `bt` at a plain `binding.irb` prompt does the same switch and runs that command. It refuses when IRB was started with plain `irb` rather than `binding.irb`, in a deprecated multi-irb session, or when the debug gem cannot be loaded; IRB first tries the copy bundled with Ruby before telling you to add `gem "debug"` to the Gemfile. The integration has no remote attach and `_` is not supported inside it.

code

ruby · 7 lines
ruby
irb(#<CsvImporter:0x...>):001> debug
irb:rdbg(#<CsvImporter:0x...>):002> info
%self = #<CsvImporter:0x...>
row = #<CSV::Row "name":"Bob" "email":nil>
i = 1
irb:rdbg(#<CsvImporter:0x...>):003> next
irb:rdbg(#<CsvImporter:0x...>):004> $ valid?

go deeper

for a junior

Know that typing debug at a binding.irb prompt turns it into a stepping debugger with an irb:rdbg prompt.

for a middle

Explain the preconditions: a binding.irb session, a loadable debug gem, no multi-irb; and that next or step start the debugger directly.

for a senior

Choose between the integrated irb:rdbg session and the debug gem's own entry points, knowing the integration lacks remote attach and _.

for a principal

Standardise a team's debugging entry point so developers are not split between consoles, and keep debugger gems in development groups only.

## Two tools, one prompt `binding.irb` gives you a console in a paused scope, but it cannot move execution forward line by line. The **debug gem** (`rdbg`, bundled with Ruby since 3.1) can. Since IRB 1.8 the two are integrated: from a `binding.irb` prompt, IRB's **`debug`** command upgrades the session into a debugger session without restarting anything. ## What happens when you type debug 1. IRB checks that the session came from `binding.irb`. 2. It loads the debug gem's session code. If `require` fails — typically because a `bundle exec` run has no `gem "debug"` in the Gemfile — it looks for the debug gem installed with Ruby itself and loads that directly. 3. It configures itself as the debug gem's user interface, renames the prompt to **`irb:rdbg`**, and inserts a one-shot breakpoint so the debugger takes over at the same place. From then on: - the debug gem's commands (`next`, `step`, `info`, `bt`, `break`, `continue`…) are recognised at the prompt; when you type one, the input line is marked `# debug command`; - IRB's own commands keep working: `show_source`, `show_doc`, `ls`, and the `$` and `@` aliases; - multi-line input, completion and IRB's prompt customisation stay available; - `help` lists both IRB's and the debug gem's commands. ## Shortcuts that start it for you IRB also registers commands named after the debug gem's — `break`, `catch`, `next`, `step`, `continue`, `finish`, `delete`, `backtrace`/`bt` and `info`. At a plain `binding.irb` prompt each one starts the debugger **and** runs that command, so `next` alone is enough to begin stepping. If the current scope already defines a method named `debug`, the `irb_debug` spelling reaches the command. ## When it refuses | Situation | What IRB says or does | |---|---| | IRB was started with plain `irb`, not `binding.irb` | "Debugging commands are only available when IRB is started with binding.irb" | | A multi-irb session (the deprecated `irb`/`jobs`/`fg` commands) is active | Warns that the debugger cannot start there | | Neither the bundle nor Ruby's own gems provide a loadable debug gem | Tells you to install it and, under `bundle exec`, to add `gem "debug"` to the Gemfile | | Already in `irb:rdbg` and you type `debug` again | "IRB is already running with a debug session." | ## Limits of the integration - `binding.irb` has no `pre:`/`do:` arguments; those belong to the debug gem's own breakpoint method. - **No remote debugging**: IRB cannot serve as the console for the debug gem's remote attach mode. - **`_` is not supported** inside `irb:rdbg`, because the debug gem evaluates the input. The opposite direction exists too: setting `RUBY_DEBUG_IRB_CONSOLE=1` makes the debug gem use IRB as its console when a debugger breakpoint is hit. ## When to reach for it - You are already at a `binding.irb` prompt in `CsvImporter#import` and want to watch the next few lines run — type `next` rather than adding more breakpoints and restarting. - You want IRB's `show_source` while stepping — the integration gives you both. - You need remote attach or breakpoint scripting — start with the debug gem's own entry points instead.

  • You start irb from the shell and type next. Why does IRB refuse?
    Debugging commands need a paused program to control. A plain `irb` session has none, so IRB prints that debugging commands are only available when IRB is started with `binding.irb`. Put `binding.irb` in the code and run the program instead.
  • Under bundle exec, debug fails with a message about adding gem "debug" to the Gemfile. What did IRB already try?
    IRB first tries `require "debug/session"` through Bundler; when that fails it searches Ruby's own gem paths for the bundled debug gem and loads it directly. The message appears only when neither works, so adding `gem "debug"` to the development group is the reliable fix.

saying these in an interview costs you the question

  • IRB's debug command works in any irb session started from the shell.
  • Switching to irb:rdbg disables show_source and other IRB commands.
  • The irb:rdbg session supports remote attach like the debug gem's own console.
  • You must exit binding.irb and restart the program to start stepping.
  • Typing next at a binding.irb prompt skips to the next binding.irb.