В некоторых языках программирования существует специальный способ указать, что "в данном поле не содержится никакого значения". В SQL, PHP и Java это NULL. В Python это None. В Ruby это называется Nil.

В Perl такое значение называется undef.

Рассмотрим это в подробностях.

Откуда берется undef?

Когда вы объявляете скалярную переменную, не присвоив ей значение, ее содержимое получает значение undef.

my $x;

Некоторые функции возвращают undef при отказе. Другие могут вернуть undef, если вернуть больше нечего.

my $x = do_something();

Функцию undef() можно использовать, чтобы сбросить значение переменной на undef:

# какой-то код
undef $x;

Также можно использовать значение, возвращаемое функцией undef(), чтобы присвоить переменной undef:

$x = undef;

Скобки после названия функции необязательны, так что в этом примере мы их опустили.

Можно видеть, что существует несколько способов присвоить переменной значение undef. Вопрос в том, что будет, если мы станем использовать такую переменную?

Однако прежде чем мы разберемся с этим, давайте узнаем кое-что еще:

Как узнать, что переменная - undef?

Функция defined() возвращает true, если данная переменная не undef. Если переменная является undef, функция вернет false.

Ее используют так:

use strict;
use warnings;
use 5.010;

my $x;

# какой-то код, который мог определить $x

if (defined $x) {
    say '$x is defined';
} else {
    say '$x is undef';
}

Какое значение на самом деле имеет undef?

Хотя undef обозначает отсутствие значения, им все равно можно пользоваться. В Perl есть два значения-по-умолчанию, используемых вместо undef.

Если использовать undef-переменную в числовой операции, она ведет себя как 0.

Если использовать ее в строковой операции, она ведет себя как пустая строка.

Например:

use strict;
use warnings;
use 5.010;

my $x;
say $x + 4, ;  # 4
say 'Foo' . $x . 'Bar' ;  # FooBar

$x++;
say $x; # 1

В этом примере переменная $x - являющаяся по умолчанию undef - ведет себя как 0 в сложении (+). В конкатенации (.) она работает как пустая строка, и снова как 0 в авто-инкременте (++).

Тем не менее, такое ее использование имеет свои недостатки. Если вы включите предупреждения, использовав выражение use warnings (что рекомендуется делать всегда), то получите два предупреждения use of uninitialized value для первых двух операций, но не для авто-инкремента:

Use of uninitialized value $x in addition (+) at ... line 6.
Use of uninitialized value $x in concatenation (.) or string at ... line 7.

Я думаю, что Perl не выдает предупреждения для авто-инкремента из-за своего великодушия. Позже мы увидим, что это частая практика в случаях, когда нужно что-то сосчитать.

Конечно, вы можете избежать предупреждений, присвоив переменной подходящее начальное значение (0 или пустую строку, в зависимости от ее предназначения), либо выборочно выключив предупреждения. Мы обсудим это в отдельной статье.