Issue #21940 has been updated by katsyoshi (Katsuyoshi MATSUMOTO). I may have another possibly related `Ruby::Box` special-global case. This may be a separate `$?` / `Process::Status` issue rather than the same root cause as `$_` or `$~`, since `$?` seems to be thread-local. Still, the symptom also looks like stale or incorrect special-global state under `Ruby::Box`. With `RUBY_BOX=1`, `$?` appears to become incorrect: ```sh RUBY_BOX=1 ruby -e '`exit 42`; puts $?' ``` On my side this prints: ```text pid 0 exit 0 ``` while without `RUBY_BOX=1`: ```sh ruby -e '`exit 42`; puts $?' ``` it correctly prints something like: ```text pid 410190 exit 42 ``` So this looks like another `Ruby::Box` special-global symptom, even if the internal cause may be different from `$_` or `$~`. ---------------------------------------- Bug #21940: Ruby::Box: `$_` returns stale value due to gvar_tbl caching https://bugs.ruby-lang.org/issues/21940#change-116689 * Author: dak2 (Daichi Kamiyama) * Status: Open * Assignee: tagomoris (Satoshi Tagomori) * ruby -v: 4.0.1 * Backport: 3.2: DONTNEED, 3.3: DONTNEED, 3.4: DONTNEED, 4.0: REQUIRED ---------------------------------------- ## Environment - Ruby Version v4.0.1 - OS: macOS 15.6.1 (arm64) - `RUBY_BOX=1` enabled ## Reproduction ```shell echo -e "a\nb" | RUBY_BOX=1 ruby -e 'gets; $_; gets; p $_' ``` ## Expected ``` "b\n" ``` The second gets reads `"b"` and sets it to `$_`. `p $_` should return the latest value. ## Actual ``` "a\n" ``` `$_` returns the stale value from the first gets. ## Root Cause `$_` is a special variable stored in `svar`. Its getter (`rb_lastline_get`) reads the current value from svar each time it is called. However, when Box is enabled, I believe `rb_gvar_get()` caches the value in the Box's `gvar_tbl` on first access. On subsequent reads, it returns the cached value directly without calling the getter. Since gets updates `$_` via `rb_lastline_set()` which bypasses `rb_gvar_set()`, the cache becomes stale. -- https://bugs.ruby-lang.org/