Bug #22283
open`defined?` does not see global variables assigned in a box
Description
Under RUBY_BOX=1, defined?($foo) returns nil for a global variable that was assigned inside the box, while reading $foo returns the assigned value and global_variables lists it.
$ ruby -e '$foo = 1; p defined?($foo)'
"global-variable"
$ RUBY_BOX=1 ruby -W:no-experimental -e '$foo = 1; p defined?($foo), $foo, global_variables.include?(:$foo)'
nil
1
true
Assignment in a box only writes to box->gvar_tbl and leaves the global entry's getter as rb_gvar_undef_getter. rb_gvar_get() consults the box table, but rb_gvar_defined() in variable.c looks only at that getter, so it never sees a box-local assignment.
The visible damage is native extension builds. mkmf's have_devel? stops its own recursion with unless defined? $have_devel, so under a box it recurses through try_link and try_do back into have_devel? until SystemStackError. This is the "Installing native extensions may fail under RUBY_BOX=1 because of stack level too deep in extconf.rb" entry in the Known issues of doc/language/box.md, and the reason RubyGems drops RUBY_BOX from the build subprocess in lib/rubygems/ext/builder.rb.
A patch is at https://github.com/ruby/ruby/pull/18586.
Related to #22275
Updated by hsbt (Hiroshi SHIBATA) 3 days ago
- Related to Misc #22275: Ruby::Box support plan for RubyGems and Bundler added