Использование переменной в качестве логического значения для проверки, была ли она установлена, хорошо, но как насчет undef? - PullRequest
0 голосов
/ 28 апреля 2020

Мне нравится использовать переменную в качестве логического значения для проверки их определения, но я запутался с этим:

my %a;
my %b = undef;
my $c;
my $d = undef;
if (!%a) { print "a\n"; }
if (!%b) { print "b\n"; }
if (!$c) { print "c\n"; }
if (!$d) { print "d\n"; }

дает:

a
c
d

так где же b? какая интерпретация?

1 Ответ

3 голосов
/ 28 апреля 2020

Полезно использовать 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 почти никогда не то, что вам нужно. Не делай этого: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...