mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
Fix global variable aliases in a box
Under RUBY_BOX=1 the box-local gvar table is keyed by the name used for access, so `alias $b $a` gives the two names separate slots and they stop being synonyms. Key it by the ID the shared rb_global_variable was created with instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
85fb0e5245
commit
ac0debb174
2 files changed
+26
-2
Notes:
git
2026-09-24 07:05:35 +00:00
No files matched your search
@@ -720,6 +720,28 @@ class TestBox < Test::Unit::TestCase
|
||||
end;
|
||||
end
|
||||
|
||||
def test_global_variable_alias_in_box
|
||||
assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
|
||||
begin;
|
||||
$aliased_original = 1
|
||||
alias $aliased_alias $aliased_original
|
||||
assert_equal [1, 1], [$aliased_original, $aliased_alias]
|
||||
$aliased_alias = 2
|
||||
assert_equal [2, 2], [$aliased_original, $aliased_alias]
|
||||
|
||||
in_box = Ruby::Box.new.eval(<<~'CODE')
|
||||
$aliased_original = 3
|
||||
seen_through_alias = $aliased_alias
|
||||
$aliased_alias = 4
|
||||
alias $aliased_in_box $aliased_original
|
||||
$aliased_in_box = 5
|
||||
[seen_through_alias, $aliased_original, $aliased_in_box]
|
||||
CODE
|
||||
assert_equal [3, 5, 5], in_box
|
||||
assert_equal [2, 2], [$aliased_original, $aliased_alias]
|
||||
end;
|
||||
end
|
||||
|
||||
def test_match_variables_are_not_cached_in_box
|
||||
assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
|
||||
begin;
|
||||
|
||||
+4
-2
@@ -551,6 +551,7 @@ struct rb_global_variable {
|
||||
rb_gvar_marker_t *marker;
|
||||
rb_gvar_compact_t *compactor;
|
||||
struct trace_var *trace;
|
||||
ID id;
|
||||
bool box_ready;
|
||||
bool box_dynamic;
|
||||
};
|
||||
@@ -638,6 +639,7 @@ global_entry_lookup(ID id, bool create_entry, bool *isolation_error)
|
||||
entry->id = id;
|
||||
entry->var = var;
|
||||
entry->ractor_local = false;
|
||||
var->id = id;
|
||||
var->counter = 1;
|
||||
var->data = 0;
|
||||
var->getter = rb_gvar_undef_getter;
|
||||
@@ -1064,7 +1066,7 @@ rb_gvar_set(ID id, VALUE val)
|
||||
|
||||
if (!isolation_error && gvar_use_box_tbl(box, entry)) {
|
||||
use_box_tbl = true;
|
||||
rb_hash_aset(box->gvar_tbl, rb_id2sym(entry->id), val);
|
||||
rb_hash_aset(box->gvar_tbl, rb_id2sym(entry->var->id), val);
|
||||
retval = val;
|
||||
// TODO: think about trace
|
||||
}
|
||||
@@ -1104,7 +1106,7 @@ rb_gvar_get(ID id)
|
||||
if (gvar_use_box_tbl(box, entry)) {
|
||||
use_box_tbl = true;
|
||||
gvars = box->gvar_tbl;
|
||||
key = rb_id2sym(entry->id);
|
||||
key = rb_id2sym(var->id);
|
||||
if (RTEST(rb_hash_has_key(gvars, key))) { // this gvar is already cached
|
||||
retval = rb_hash_aref(gvars, key);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user