From f36c61d27fcdc47d4aa34e8a3b52590aac08bb69 Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Thu, 1 Feb 2024 16:19:03 +0000 Subject: [ruby/irb] Reset history counter even when @loaded_history_lines is not defined (https://github.com/ruby/irb/pull/853) The issue (https://github.com/ruby/debug/issues/1064) is caused by a combination of factors: 1. When user starts an IRB session without a history file, the `@loaded_history_lines` ivar is not defined. 2. If the user then starts the `irb:rdbg` session, the history counter is not set, because the `@loaded_history_lines` is not defined. 3. Because `irb:rdbg` saves the history before passing Ruby expression to the debugger, it saves the history with duplicated lines. The number grows in exponential order. 4. When the user exits the `irb:rdbg` session, the history file could be bloated with duplicated lines. This commit fixes the issue by resetting the history counter even when `@loaded_history_lines` is not defined. https://github.com/ruby/irb/commit/4afc98c258 --- lib/irb/history.rb | 2 +- test/irb/test_history.rb | 51 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/lib/irb/history.rb b/lib/irb/history.rb index 50fe1ce229..90aa9f0bcf 100644 --- a/lib/irb/history.rb +++ b/lib/irb/history.rb @@ -5,7 +5,7 @@ module IRB end def reset_history_counter - @loaded_history_lines = self.class::HISTORY.size if defined? @loaded_history_lines + @loaded_history_lines = self.class::HISTORY.size end def load_history diff --git a/test/irb/test_history.rb b/test/irb/test_history.rb index f7ba2b9d33..fef42b4982 100644 --- a/test/irb/test_history.rb +++ b/test/irb/test_history.rb @@ -251,10 +251,6 @@ module TestIRB class IRBHistoryIntegrationTest < IntegrationTestCase def test_history_saving_with_debug - if ruby_core? - omit "This test works only under ruby/irb" - end - write_history "" write_ruby <<~'RUBY' @@ -293,6 +289,53 @@ module TestIRB HISTORY end + def test_history_saving_with_debug_without_prior_history + tmpdir = Dir.mktmpdir("test_irb_history_") + # Intentionally not creating the file so we test the reset counter logic + history_file = File.join(tmpdir, "irb_history") + + write_rc <<~RUBY + IRB.conf[:HISTORY_FILE] = "#{history_file}" + RUBY + + write_ruby <<~'RUBY' + def foo + end + + binding.irb + + foo + RUBY + + output = run_ruby_file do + type "'irb session'" + type "next" + type "'irb:debug session'" + type "step" + type "irb_info" + type "puts Reline::HISTORY.to_a.to_s" + type "q!" + end + + assert_include(output, "InputMethod: RelineInputMethod") + # check that in-memory history is preserved across sessions + assert_include output, %q( + ["'irb session'", "next", "'irb:debug session'", "step", "irb_info", "puts Reline::HISTORY.to_a.to_s"] + ).strip + + assert_equal <<~HISTORY, File.read(history_file) + 'irb session' + next + 'irb:debug session' + step + irb_info + puts Reline::HISTORY.to_a.to_s + q! + HISTORY + ensure + FileUtils.rm_rf(tmpdir) + end + def test_history_saving_with_nested_sessions write_history "" -- cgit v1.2.3