summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authordak2 <dawt2h@gmail.com>2026-03-05 00:33:49 +0900
committerSatoshi Tagomori <tagomoris@gmail.com>2026-05-01 12:10:38 +0900
commitf89b07ef0046257dd796a2e615cc063072114f16 (patch)
tree808fbb77c81495b53e0e6c5f8153e655bf7a3791 /test
parent81f2fcae4e25866963ac2a69f4d84a331692f512 (diff)
Mark `$_` as box-dynamic to bypass Box gvar_tbl cache
`$_` is updated through svar (rb_lastline_set), bypassing rb_gvar_set, so the Box gvar_tbl cache is never invalidated and returns a stale value. Call rb_gvar_box_dynamic so gvar_use_box_tbl() skips the cache. Fixes [Bug #21940](https://bugs.ruby-lang.org/issues/21940)
Diffstat (limited to 'test')
-rw-r--r--test/ruby/test_box.rb43
1 files changed, 43 insertions, 0 deletions
diff --git a/test/ruby/test_box.rb b/test/ruby/test_box.rb
index e4afb8fcc0..8644b84bcd 100644
--- a/test/ruby/test_box.rb
+++ b/test/ruby/test_box.rb
@@ -583,6 +583,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