Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my hash not undef?

Tags:

hash

perl

I have the following (idealised from a bug) short script in Perl:

my %metadata = undef;
if (defined %metadata)
{
    print "defined";
}

For some reason the output of the program is always "defined". So setting the hash to be "undefined" somehow makes it defined. Is it defined as being "undefined"?

EDIT:

This is an idealised case, in an attempt to replicate the problem. What I'm actually doing is more like:

my %metadata = my_sub_function();
if (defined %metadata)
{
    print "defined";
}

Where the output of my_sub_function may be undef, () or a populated hash, and I only want to print "defined" in the last of these cases.

EDIT 2:

Incidentally I have found that

if (scalar(keys %metadata)

behaves correctly for (), but still not for undef.

like image 784
Richard J Avatar asked Oct 18 '10 10:10

Richard J


1 Answers

If your function returns undef and that undef is placed in the hash, auto-stringification changes that undef to be '' and you end up with: %metadata = ( '' => undef ).

If your function needs to return either undef, () or a proper hash and you need to test all three cases separately, I'd suggest:

my %metadata = my_sub_function();
if ( !scalar keys %metadata ) {
  print "An empty list () was returned\n"
} elsif (
  scalar keys %metadata == 1 and
  exists $metadata{''} and
  !defined $metadata{''}
) {
  print "undef or '' was returned\n";
} else {
  print "A hash was hopefully returned\n";
}

You could test it with the following my_sub_functions:

sub my_sub_function { return ()                 } # 1st case
sub my_sub_function { return undef              } # 2nd case
sub my_sub_function { return ( a => 1, b => 2 ) } # 3rd case
sub my_sub_function { return qw/not a hash/     } # unhandled case

Happy hacking

like image 123
mfontani Avatar answered Nov 15 '22 05:11

mfontani