-
Notifications
You must be signed in to change notification settings - Fork 138
Description
Versions
- irb: 1.15.2
- debug: 1.11.0
- Ruby: 3.3.6
- OS: MacOS
Description
When running an IRB session launched from a script under debug with RUBY_DEBUG_IRB_CONSOLE=true, command history is not written to ~/.irb_history.
The same script, run without RUBY_DEBUG_IRB_CONSOLE=true, saves history as expected.
Reproduction
# script.rb
require "debug"
require "irb"
IRB.startRun:
RUBY_DEBUG_IRB_CONSOLE=true bundle exec ruby script.rb
# type several IRB commands, then exitCheck ~/.irb_history — the commands you typed aren’t appended.
Control case (works):
bundle exec ruby script.rb
# type several IRB commands, then exitNow ~/.irb_history contains the new commands.
Expected behavior
The interactive IRB session started by the script should append commands to ~/.irb_history even if RUBY_DEBUG_IRB_CONSOLE is set.
Analysis
When RUBY_DEBUG_IRB_CONSOLE=true is set, debug eagerly creates its own IRB console in the background.
That causes IRB’s “first session” detection (via MAIN_CONTEXT) to treat the user-visible session as nested rather than the initial one.
Because IRB only persists history from the first session, the foreground session never saves history.
The logic that gates history saving based on the main vs. nested session seems tied to this commit in Ruby’s repo:
Why I think this is a bug
From a user perspective, the interactive session the user is typing into should save history regardless of whether a background IRB console was created by a debugger.
Today, enabling RUBY_DEBUG_IRB_CONSOLE=true flips that behavior in a surprising and unintuitive way.
Workarounds
- Run without
RUBY_DEBUG_IRB_CONSOLE=true(history is saved). - Add to
~/.irbrc
if defined?(DEBUGGER__) && ENV["RUBY_DEBUG_IRB_CONSOLE"] == "true"
IRB.conf[:AT_EXIT] << proc {
if IRB.conf[:MAIN_CONTEXT]&.io.respond_to?(:save_history)
IRB.conf[:MAIN_CONTEXT].io.save_history
end
}
endContext
Discovered while migrating from Pry/Byebug to IRB + debug.