Полезно использовать Data :: Dumper для исследования запутанных Perl структур данных.
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my %a;
my %b = undef;
say Dumper $_ for \%a, \%b;
Это приводит к следующему выводу:
$VAR1 = {};
$VAR1 = {
'' => undef
};
Итак, ваш второй пример дает странный ха sh, который не содержит ничего полезного, но который явно не является пустым ха sh.
Если вы посмотрите на perldo c perldata , вы увидите, что он содержит это:
Если вы оцениваете ha sh в скалярном контексте, он возвращает ложное значение, если ha sh пусто. Если есть какие-либо пары ключ / значение, он возвращает истинное значение.
И когда вы оцениваете выражение в операторе if
, оно оценивается в скалярном контексте. Итак, поскольку у вашего ha sh есть ключ (хотя и пустая строка), он возвращает true в этом контексте.
Все это оставляет нас в вопросе, как нам удалось создать ha sh, который выглядит например, запустив:
my %b = undef;
Вы инициализируете ха sh из списка.
my %hash = ('a key', 'a value', 'another key', 'another value');
По (надеюсь) очевидным причинам, лучше, если список имеет четное число элементов. Фактически, под use warnings
вы получите предупреждение, если будете использовать список с нечетным числом элементов.
Так что Perl интерпретирует ваш код как:
my %b = (undef);
И если вы попросите их, вы получите предупреждение.
Но если вы настаиваете на использовании списка с нечетным числом элементов, Perl просто добавит дополнительный неопределенный элемент в конец списка. Таким образом, ваш код становится:
my %b = (undef, undef);
И так как ключ ha sh должен быть строкой, Perl молча преобразует этот первый undef
в пустую строку.
my %b = ('', undef);
И это ха sh, с которым вы в конечном итоге.
Назначение undef
массиву или ха sh почти никогда не то, что вам нужно. Не делай этого: -)