Skip to content

Commit c41f460

Browse files
authored
Restore MAIN_CONTEXT correctly (#937)
1 parent a5a2337 commit c41f460

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

lib/irb.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,7 @@ def debug_readline(binding)
992992
def run(conf = IRB.conf)
993993
in_nested_session = !!conf[:MAIN_CONTEXT]
994994
conf[:IRB_RC].call(context) if conf[:IRB_RC]
995+
prev_context = conf[:MAIN_CONTEXT]
995996
conf[:MAIN_CONTEXT] = context
996997

997998
save_history = !in_nested_session && conf[:SAVE_HISTORY] && context.io.support_history_saving?
@@ -1014,6 +1015,9 @@ def run(conf = IRB.conf)
10141015
eval_input
10151016
end
10161017
ensure
1018+
# Do not restore to nil. It will cause IRB crash when used with threads.
1019+
IRB.conf[:MAIN_CONTEXT] = prev_context if prev_context
1020+
10171021
RubyVM.keep_script_lines = keep_script_lines_backup if defined?(RubyVM.keep_script_lines)
10181022
trap("SIGINT", prev_trap)
10191023
conf[:AT_EXIT].each{|hook| hook.call}

test/irb/test_irb.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,26 @@ def test_empty_input_echoing_behaviour
125125
end
126126
end
127127

128+
class NestedBindingIrbTest < IntegrationTestCase
129+
def test_current_context_restore
130+
write_ruby <<~'RUBY'
131+
binding.irb
132+
RUBY
133+
134+
output = run_ruby_file do
135+
type '$ctx = IRB.CurrentContext'
136+
type 'binding.irb'
137+
type 'p context_changed: IRB.CurrentContext != $ctx'
138+
type 'exit'
139+
type 'p context_restored: IRB.CurrentContext == $ctx'
140+
type 'exit'
141+
end
142+
143+
assert_include output, '{:context_changed=>true}'
144+
assert_include output, '{:context_restored=>true}'
145+
end
146+
end
147+
128148
class IrbIOConfigurationTest < TestCase
129149
Row = Struct.new(:content, :current_line_spaces, :new_line_spaces, :indent_level)
130150

0 commit comments

Comments
 (0)