Как проверить что в Perl переменной содержится undef

Задача. В коде на языке программирования Perl есть переменная. Нужно проверить является ли значение этой переменной undef или нет.

Решение

В переменной содержится undef только если функция defined для этой переменной возвращает ложь. Вот код который выводит текст если в переменной содержится undef:

▶ Run
#!/usr/bin/perl

my $foo;

if ( !defined($foo) ) {
    print "foo is undef";
}

Неправильные решения

Для того чтобы проверить находится ли undef в переменной нужно использовать defined. Но часто бывает что для проверки на undef используют другие, неправильные способы.

Вот первый пример как не нужно делать:

▶ Run
#!/usr/bin/perl

my $foo;

if ( !$foo ) { # error!
    print "foo is undef";
}

Этот пример действительно выведет строку foo is undef если в переменной $foo содержится значение undef, но код выведет эту строчку и в других случаях. Например, если в $foo содержится число 0 или пустая строка ''. Этот код — это не проверка на то что в $foo содержится undef, а проверка на то что в $foo содержится значение-ложь, а это совершенно не то же самое что undef.

Вот еще один пример ошибочной проверки на undef:

▶ Run
#!/usr/bin/perl

my $foo;

if ( $foo == undef ) { # error!
    print "foo is undef";
}

Тут прямо все совершенно неправильно. Если в переменной $foo содержится значение undef, то этот код выведет строчку foo is undef, но код выведет эту строчку и в других случаях. Например если в переменной $foo содержится строка 'Hello'.

Оператор == предназначен для сравнения чисел. Перед тем как произвести сравнение этот оператор преобразует свои аргументы в числа. Переменная $foo в которой находится undef становится числом 0. И undef справа от оператора тоже становится числом 0. Ноль равен нулю, условие срабатывает. Но нулем становятся и некоторые строки, например 'Hello'.

Если добавить в этот код use strict; и use warnings;, то Perl выведет строку foo is undef, но так же сообщит о том что происходит что-то странное:

Use of uninitialized value in numeric eq (==) at script.pl line 8.
Use of uninitialized value $foo in numeric eq (==) at script.pl line 8.
foo is undef

А вообще это всегда очень хорошая практика всегда использовать use strict; и use warnings;.

Связанные темы

Другие статьи

Комментарии