Project

General

Profile

Actions

Bug #22307

open

Ruby::Box: assignments to C-backed global variables do not reach C

Bug #22307: Ruby::Box: assignments to C-backed global variables do not reach C

Added by hsbt (Hiroshi SHIBATA) 10 days ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 4.1.0dev (2026-09-10T03:20:50Z master fe58143f12) +YJIT +MN +PRISM [arm64-darwin27]
[ruby-core:126661]

Description

Under RUBY_BOX=1, assigning a global variable backed by a C variable only updates a per-box table. The setter never runs and the interpreter keeps reading the C variable. This happens in the main box too.

$ RUBY_BOX=1 ruby --disable-gems -e '$/ = "!"; p "hello!".chomp, [$/, $-0]; $/ = 1; $-a = 1; p $stdout.equal?(STDOUT)'
"hello!"
["!", "\n"]
false

Without RUBY_BOX, chomp returns "hello", $-0 follows $/, and $/ = 1 raises TypeError. 4.0.6 behaves the same.

gvar_use_box_tbl (variable.c:1025) sends every variable in a user box, the main box included, through box->gvar_tbl unless it is marked box_dynamic or box_ready. The first read clones the getter's value into the table and later writes stay there. So $/ and $-0 get separate slots for one rb_rs, $stdout becomes a copy of STDOUT, and validating setters never run.

So far this has been fixed one variable at a time with those two marks, in #21940 ($_), #21933 ($~) and #21991 ($!, $@). The open #22280, #22282 and #21867 have PRs that do the same. https://github.com/ruby/ruby/pull/18711 covers the rest in the main box by skipping the table for any variable whose setter is not the plain Ruby one, so the main box behaves like Ruby without boxes.

Optional boxes keep the table, and TestBox#test_global_variables asserts that $-0 and $, set in one box stay there. That holds only for Ruby code reading the variable. C code in every box reads the one C variable.

$ RUBY_BOX=1 ruby --disable-gems -e 'p Ruby::Box.new.eval(%q{$/ = "!"; ["hello!".chomp, $/, $-0]})'
["hello!", "!", "\n"]

I would like a decision on what these variables mean in an optional box. The first option keeps the box-local copy and accepts that the interpreter ignores it, which is where #18711 stops. The second shares them across all boxes like box_dynamic and changes test_global_variables. The third makes the C side per box, so every reader of rb_rs and the like looks it up through the current box.


Related issues 7 (2 open5 closed)

Related to Ruby - Misc #22275: Ruby::Box support plan for RubyGems and BundlerOpenActions
Related to Ruby - Bug #21940: Ruby::Box: `$_` returns stale value due to gvar_tbl cachingClosedtagomoris (Satoshi Tagomori)Actions
Related to Ruby - Bug #21933: Ruby::Box: named capture local variable can become nil after non-matching linesClosedActions
Related to Ruby - Bug #21991: `$!` stays as the first exception in Ruby BoxClosedtagomoris (Satoshi Tagomori)Actions
Related to Ruby - Bug #22280: Ruby::Box breaks $? after Kernel#system / IO.popenClosedActions
Related to Ruby - Bug #22282: $VERBOSE and $DEBUG assignments have no effect under RUBY_BOX=1OpenActions
Related to Ruby - Bug #21867: enabling Ruby::Box changes puts/warn to no longer use $stdout/$stderrClosedtagomoris (Satoshi Tagomori)Actions

Updated by hsbt (Hiroshi SHIBATA) 10 days ago Actions #1

  • Related to Misc #22275: Ruby::Box support plan for RubyGems and Bundler added

Updated by hsbt (Hiroshi SHIBATA) 10 days ago Actions #2

  • Related to Bug #21940: Ruby::Box: `$_` returns stale value due to gvar_tbl caching added

Updated by hsbt (Hiroshi SHIBATA) 10 days ago Actions #3

  • Related to Bug #21933: Ruby::Box: named capture local variable can become nil after non-matching lines added

Updated by hsbt (Hiroshi SHIBATA) 10 days ago Actions #4

  • Related to Bug #21991: `$!` stays as the first exception in Ruby Box added

Updated by hsbt (Hiroshi SHIBATA) 10 days ago Actions #5

  • Related to Bug #22280: Ruby::Box breaks $? after Kernel#system / IO.popen added

Updated by hsbt (Hiroshi SHIBATA) 10 days ago Actions #6

  • Related to Bug #22282: $VERBOSE and $DEBUG assignments have no effect under RUBY_BOX=1 added

Updated by hsbt (Hiroshi SHIBATA) 10 days ago Actions #7

  • Related to Bug #21867: enabling Ruby::Box changes puts/warn to no longer use $stdout/$stderr added
Actions

Also available in: PDF Atom