Проблема конструкции unless в Perl

В языке программирования Perl, как и во множестве других языков программирования есть конструкция if:

▶ Run
#!/usr/bin/perl

my $value;

if (!defined $value) {
    print 'value must be defined';
}

Тело if выполняется в том случае если условие возвращает истину.

Но кроме конструкции if еще есть и обратная конструкция unless. Тело unless выполняется в случае если условие возвращает ложь. Вот код, который работает точно так же как предыдущий, но написанный с использованием unless:

▶ Run
#!/usr/bin/perl

my $value;

unless (defined $value) {
    print 'value must be defined';
}

Если смотреть на эти два примера, то видно что при использовании unless в коде используется меньше конструкций (не приходится писать !), но сам код получается длиннее на 3 символа.

Кроме того что приходится больше печатать, при использовании unless может возникнуть еще одна проблема. Представим что нам нужно дополнить наш код с unless. Сейчас он выполняет какие-то действия когда в переменной $value находится undef. Возникла задача выполнить действие в случае обратной ситуации — когда в $value находится что угодно, но не undef. Вполне естественная реакция в данной ситуации дописать else блок:

▶ Run
#!/usr/bin/perl

my $value;

unless (defined $value) {
    print 'value must be defined';
} else {
    print 'value is defined';
}

Получился работающий код и этот код было просто написать, но получился плохой код. Этот код сложно чинить и понимать. Вместо этого кода нужно было бы написать прямо:

▶ Run
#!/usr/bin/perl

my $value;

if (defined $value) {
    print 'value is defined';
} else {
    print 'value must be defined';
}

К сожалению, если изначально в коде используется unless, то есть большой соблазн не менять его на if, а просто написать else. Но из-за этого получается плохой код.

Существует мнение что возможность написать unless-else это вообще ошибка в дизайне языка. И такая конструкция должна выдавать ошибку, вместо того чтобы работать.

unless, так же как и if может быть использовано в постфиксном варианте:

▶ Run
#!/usr/bin/perl

my $value;

print 'value must be defined' unless defined $value;

При использовании постфиксной записи unless проблемы unless-else не возникает, так как в таком варианте else вообще некуда вписать.

Итого рекомендация. Никогда не использовать конструкцию unless ( $bool ) { ... }, так как это приводит к ухудшению читаемости кода. Про использование unless в постфиксном варианте такой строгой рекомендации нет. Использовать или нет постфиксный unless это дело договоренности в команде и дело вкуса. Автор предпочитает вообще никогда не использовать unless.

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

Комментарии