2013-08-06 1 views
1

Следующий код печатает Key defined 3. Почему Perl определяет ключ ABC? Я ожидал, что все три проверки будут ложными. Что я делаю неправильно?Perl, определяющий неопределенные ключи

#!/usr/bin/perl 
use warnings; 
use strict; 

my %Hash; 

if(defined $Hash{'ABC'}) 
{ 
    printf("Key defined 1\n"); 
} 

if(defined $Hash{'ABC'}{'Status'}) 
{ 
    printf("Key defined 2\n"); 
} 

if(defined $Hash{'ABC'}) 
{ 
    printf("Key defined 3\n"); 
} 

ответ

4

Это $Hash{'ABC'}{'Status'} autovivifies ключ ABC (см perldoc perlref и wikipedia):

use warnings; 
use strict; 
use Data::Dumper; 

my %Hash; 

if(defined $Hash{'ABC'}) 
{ 
    printf("Key defined 1\n"); 
} 
print Dumper(\%Hash); 

if(defined $Hash{'ABC'}{'Status'}) 
{ 
    printf("Key defined 2\n"); 
} 
print Dumper(\%Hash); 

if(defined $Hash{'ABC'}) 
{ 
    printf("Key defined 3\n"); 
} 
print Dumper(\%Hash); 

__END__ 

$VAR1 = {}; 
$VAR1 = { 
      'ABC' => {} 
     }; 
Key defined 3 
$VAR1 = { 
      'ABC' => {} 
     }; 

Смотрите также Data::Diver и autovivification pragma, которые предотвращают autovivification.

2
$Hash{'ABC'}{'Status'} 

коротка для

$Hash{'ABC'}->{'Status'} 

То, что вы есть разыменования. Когда переменная, являющаяся разыменованной, не определена, автовивитация срабатывает, чтобы создать соответствующий тип переменной. Это делает выше эквивалент

($Hash{'ABC'} //= {})->{'Status'} 

Вы можете избежать autovivification, избегая разыменования что-то неопределенного

if ($Hash{'ABC'} && defined $Hash{'ABC'}{'Status'}) 

Или вы можете использовать no autovivification;

no autovivification; 
if (defined $Hash{'ABC'}{'Status'})