I have some code that feels like a bug in Perl, but am I missing something? Basically, when I localize a hash element in a shared hash, the element still exists (with the undef
value) after it leaves the scope.
For example:
use threads;
use threads::shared;
my $hash1 = {};
{ local $hash1->{'desc'} = "blah" }
print exists($hash1->{'desc'}) ? "Hash: existsn" : "Hash: does not existn";
my $hash2 = shared_clone({});
{ local $hash2->{'desc'} = "blah" }
print exists($hash2->{'desc'}) ? "Shared hash: existsn" : "Shared hash: does not existn";
print "Shared hash: is undefn" if !defined($hash2{'desc'});
Which prints the following for perl v5.34.0:
Hash: does not exist
Shared hash: exists
Shared hash: is undef
I found a very similar bug that was apparently fixed in perl v5.8.0 for tied hashes. I’m wondering if shared hashes are something different than “tied” and therefore still have the bug?
The bug identified in perldoc perl58delta
as being fixed:
Localised hash elements (and %ENV) are correctly unlocalised to not
exist, if they didn’t before they were localised.use Tie::Hash; tie my %tied_hash => 'Tie::StdHash'; ... # Nothing has set the FOO element so far { local $tied_hash{FOO} = 'Bar' } # This used to print, but not now. print "exists!n" if exists $tied_hash{FOO};
As a side effect of this fix, tied hash interfaces must define the
EXISTS and DELETE methods.