Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why an undef variable becomes {} without define?

Tags:

perl

I'm working on review webmin's source code.

($wuser) = grep { $_->{'name'} eq $in{'user'} } &acl::list_users();

If we pass $in{'user'} like ?user=notexist, variable $wuser will be undef, isn't it?

The abstract code descript what happened below.

# $wuser is undef now.
#die Dumper($wuser);
if($wuser){die 'not die here';}
        if ($wuser->{'pass'} eq 'x') {
                #never reach here.
                die 'not die in branch 1';
        }
        elsif ($wuser->{'pass'} eq '*LK*' ||
               $wuser->{'pass'} =~ /^\!/) {
                #never reach here too.
                die 'not die in branch 2';
        }
if($wuser){die 'so....why die here '.Dumper($wuser);}
# $wuser is {} now.
}

So...when and how an undef variable becomes {} without any define...

like image 211
minty_he Avatar asked Sep 05 '26 04:09

minty_he


1 Answers

The problem here is a Perl feature called "autovivification". Basically, it means that if you treat an undefined Perl variable as a type of reference, then Perl will create a reference of that type and store it in your variable.

So your problem starts when you execute this statement:

if ($wuser->{'pass'} eq 'x')

Perl sees you treating $wuser as a hash reference, so it creates an empty hash and stores a reference to that hash in $wuser. It can then look up the "pass" key in that hash and find that it doesn't exist.

Usually, this is seen as a feature. You can run code like:

my $hash; # created as undef
$hash->{foo}{bar}{baz} = 1;

And Perl will create this data structure for you:

{
  'foo' => {
    'bar' => {
      'baz' => 1
    }
  }
};

without you needing to go to the trouble of creating all the intermediate levels of the hash.

Of course, your code is rather artificial. You know that $wuser is false when you start looking for keys. All references are true, so a false reference can never contain keys.

like image 91
Dave Cross Avatar answered Sep 08 '26 19:09

Dave Cross



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!