This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #35865, #43011] FETCH after autovivifying
After autovivification, perl should not assume that the value it has
assigned to a magical scalar is the one that would have been returned.
The result of this assumption is that any tie class that copies things
assigned to it will cause autovivification to assign to a temporary
aggregate without warning, in cases like this:
$tied{nonexistent}{foo} = 7;
The hash implicitly assigned to $tied{nonexistent} ends up being freed
after the =7 assignment.
This commit changes autovivification to do FETCH immediately after
doing STORE.
This required changing some recently-added tests in gmagic.t.
Without this change, you end up with horrific workarounds (using B.pm
to get the reference count), like the one in JE::Object (which I’m
pasting here, in case it has changed by the time you read this):
sub STORE {
my($self, $key, $val) = @_;
my $global = $self->global;
if(ref $val eq 'HASH' && !blessed $val
&& !%$val && svref_2object($val)->REFCNT == 2) {
$val = tie %$val, __PACKAGE__, __PACKAGE__->new(
$global);
} elsif (ref $val eq 'ARRAY' && !blessed $val && !@$val &&
svref_2object($val)->REFCNT == 2) {
require JE::Object::Array;
$val = tie @$val, 'JE::Object::Array',
JE::Object::Array->new($global);
}
$self->prop($key => $global->upgrade($val))
}