summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--io.c1
-rw-r--r--test/ruby/test_box.rb43
2 files changed, 44 insertions, 0 deletions
diff --git a/io.c b/io.c
index 7088f036c5..3d2e340b03 100644
--- a/io.c
+++ b/io.c
@@ -15738,6 +15738,7 @@ Init_IO(void)
rb_define_virtual_variable("$_", get_LAST_READ_LINE, set_LAST_READ_LINE);
rb_gvar_ractor_local("$_");
+ rb_gvar_box_dynamic("$_");
rb_define_method(rb_cIO, "initialize_copy", rb_io_init_copy, 1);
rb_define_method(rb_cIO, "reopen", rb_io_reopen, -1);
diff --git a/test/ruby/test_box.rb b/test/ruby/test_box.rb
index 1e162279d4..313a013c07 100644
--- a/test/ruby/test_box.rb
+++ b/test/ruby/test_box.rb
@@ -551,6 +551,49 @@ class TestBox < Test::Unit::TestCase
end;
end
+ def test_lastline_not_cached_in_box
+ assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
+ begin;
+ r, w = IO.pipe
+ w.write("first\nsecond\n")
+ w.close
+ STDIN.reopen(r)
+ via_gets = Ruby::Box.new.eval(<<~'CODE')
+ gets
+ _ = $_
+ gets
+ $_
+ CODE
+ assert_equal "second\n", via_gets
+ end;
+ end
+
+ def test_lastline_not_cached_in_nested_boxes
+ assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
+ begin;
+ r, w = IO.pipe
+ w.write("outer1\ninner1\ninner2\nouter2\n")
+ w.close
+ STDIN.reopen(r)
+ inner_via_gets, outer_via_gets = Ruby::Box.new.eval(<<~'CODE')
+ gets
+ _ = $_
+
+ inner_result = Ruby::Box.new.eval(<<~'INNER')
+ gets
+ _ = $_
+ gets
+ $_
+ INNER
+
+ gets
+ [inner_result, $_]
+ CODE
+ assert_equal "inner2\n", inner_via_gets
+ assert_equal "outer2\n", outer_via_gets
+ end;
+ end
+
def test_load_path_and_loaded_features
setup_box