diff --git a/lib/irb.rb b/lib/irb.rb index f7019ab0e..18c0b49c0 100644 --- a/lib/irb.rb +++ b/lib/irb.rb @@ -962,20 +962,26 @@ def debug_readline(binding) # # Irb#eval_input will simply return the input, and we need to pass it to the # debugger. - input = if IRB.conf[:SAVE_HISTORY] && context.io.support_history_saving? - # Previous IRB session's history has been saved when `Irb#run` is exited We need - # to make sure the saved history is not saved again by resetting the counter - context.io.reset_history_counter + input = nil + forced_exit = catch(:IRB_EXIT) do + if IRB.conf[:SAVE_HISTORY] && context.io.support_history_saving? + # Previous IRB session's history has been saved when `Irb#run` is exited We need + # to make sure the saved history is not saved again by resetting the counter + context.io.reset_history_counter - begin - eval_input - ensure - context.io.save_history + begin + input = eval_input + ensure + context.io.save_history + end + else + input = eval_input end - else - eval_input + false end + Kernel.exit if forced_exit + if input&.include?("\n") @line_no += input.count("\n") - 1 end diff --git a/lib/irb/command/exit.rb b/lib/irb/command/exit.rb index 3109ec16e..b4436f034 100644 --- a/lib/irb/command/exit.rb +++ b/lib/irb/command/exit.rb @@ -8,10 +8,8 @@ class Exit < Base category "IRB" description "Exit the current irb session." - def execute(*) + def execute(_arg) IRB.irb_exit - rescue UncaughtThrowError - Kernel.exit end end end diff --git a/lib/irb/command/force_exit.rb b/lib/irb/command/force_exit.rb index c2c5542e2..14086aa84 100644 --- a/lib/irb/command/force_exit.rb +++ b/lib/irb/command/force_exit.rb @@ -8,10 +8,8 @@ class ForceExit < Base category "IRB" description "Exit the current process." - def execute(*) + def execute(_arg) throw :IRB_EXIT, true - rescue UncaughtThrowError - Kernel.exit! end end end diff --git a/test/irb/command/test_force_exit.rb b/test/irb/command/test_force_exit.rb index 9e86c644d..191a78687 100644 --- a/test/irb/command/test_force_exit.rb +++ b/test/irb/command/test_force_exit.rb @@ -47,17 +47,5 @@ def foo assert_match(/irb\(main\):001> 123/, output) end - - def test_forced_exit_out_of_irb_session - write_ruby <<~'ruby' - at_exit { puts 'un' + 'reachable' } - binding.irb - exit! # this will call exit! method overrided by command - ruby - output = run_ruby_file do - type "exit" - end - assert_not_include(output, 'unreachable') - end end end diff --git a/test/irb/test_debugger_integration.rb b/test/irb/test_debugger_integration.rb index 839a0d43f..eca40c570 100644 --- a/test/irb/test_debugger_integration.rb +++ b/test/irb/test_debugger_integration.rb @@ -244,28 +244,46 @@ def test_catch def test_exit write_ruby <<~'RUBY' binding.irb - puts "hello" + puts "he" + "llo" RUBY output = run_ruby_file do - type "next" + type "debug" type "exit" end - assert_match(/irb\(main\):001> next/, output) + assert_match(/irb:rdbg\(main\):002>/, output) + assert_match(/hello/, output) + end + + def test_force_exit + write_ruby <<~'RUBY' + binding.irb + puts "he" + "llo" + RUBY + + output = run_ruby_file do + type "debug" + type "exit!" + end + + assert_match(/irb:rdbg\(main\):002>/, output) + assert_not_match(/hello/, output) end def test_quit write_ruby <<~'RUBY' binding.irb + puts "he" + "llo" RUBY output = run_ruby_file do - type "next" + type "debug" type "quit!" end - assert_match(/irb\(main\):001> next/, output) + assert_match(/irb:rdbg\(main\):002>/, output) + assert_not_match(/hello/, output) end def test_prompt_line_number_continues