diff --git a/lib/irb.rb b/lib/irb.rb index 3830867e6a..218920bc41 100644 --- a/lib/irb.rb +++ b/lib/irb.rb @@ -989,7 +989,7 @@ module IRB conf[:AT_EXIT].each{|hook| hook.call} context.io.save_history if save_history - Kernel.exit(0) if forced_exit + Kernel.exit if forced_exit end end diff --git a/lib/irb/cmd/force_exit.rb b/lib/irb/cmd/force_exit.rb index 2b9f296865..7e9b308de0 100644 --- a/lib/irb/cmd/force_exit.rb +++ b/lib/irb/cmd/force_exit.rb @@ -13,7 +13,7 @@ module IRB def execute(*) throw :IRB_EXIT, true rescue UncaughtThrowError - Kernel.exit(0) + Kernel.exit! end end end diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb index 2bf3d5e0f1..aaf2f335e2 100644 --- a/lib/irb/workspace.rb +++ b/lib/irb/workspace.rb @@ -90,11 +90,11 @@ EOF IRB.conf[:__MAIN__] = @main @main.singleton_class.class_eval do private - define_method(:exit) do |*a, &b| - # Do nothing, will be overridden - end define_method(:binding, Kernel.instance_method(:binding)) define_method(:local_variables, Kernel.instance_method(:local_variables)) + # Define empty method to avoid delegator warning, will be overridden. + define_method(:exit) {|*a, &b| } + define_method(:exit!) {|*a, &b| } end @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, *@binding.source_location) end diff --git a/test/irb/cmd/test_force_exit.rb b/test/irb/cmd/test_force_exit.rb index 191a786872..9e86c644d6 100644 --- a/test/irb/cmd/test_force_exit.rb +++ b/test/irb/cmd/test_force_exit.rb @@ -47,5 +47,17 @@ module TestIRB 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_cmd.rb b/test/irb/test_cmd.rb index 7d7353281e..349d2c0457 100644 --- a/test/irb/test_cmd.rb +++ b/test/irb/test_cmd.rb @@ -58,9 +58,7 @@ module TestIRB "irb_info", main: main ) - # Because the main object is frozen, IRB would wrap a delegator around it - # Which's exit! method can't be overridden and would raise a warning - assert_match(/delegator does not forward private method #exit\!/, err) + assert_empty(err) assert_match(/RUBY_PLATFORM/, out) end end