perl5
perl5 copied to clipboard
`local $h{$k}` doesn't remove previously non-existing key from shared hashes
core threads local
Description
local $h{$k} should remove the element if it didn't previously exist. In other words, local $h{$k} should restore the state of existence of $h{$k}.
This isn't explicitly documented as far as I can tell, but perl58delta indicates that version 5.8 introduced a fix to obtain that behaviour for tied hashes. (Adding EXISTS and DELETE handlers was required to fix this!)
However, shared hashes still behave incorrectly. The element is left existing but undef.
Steps to Reproduce
use strict;
use warnings;
use threads;
use threads::shared;
sub test {
my $name = shift;
my $h = shift;
{ local $h->{ x } = "blah"; }
printf( "%s: %s\n",
$name,
( !exists( $h->{ x } ) ? "!exists"
: !defined( $h->{ x } ) ? "exists && !defined"
: "exists && defined"
)
);
}
{ my %h; test( "Normal hash", \%h ); }
{ my %h :shared; test( "Shared hash", \%h ); }
Expected behavior
Consistent behaviour is expected. Instead, we get
Normal hash: !exists
Shared hash: exists && !defined
Perl configuration
$ perl -v | grep 'This is'
This is perl 5, version 38, subversion 0 (v5.38.0) built for x86_64-linux-thread-multi
From https://stackoverflow.com/q/78537778/589924
Yeah, this doesn't seem to be handled right now. The element magic probably needs a local handler.