Лаконичность кода
1. Сокращённая форма записи, основанная на ||
Если это не ухудшает читабельность кода, приветствуется использование сокращённой формы записи, основанной на применении логического оператора «или». Например:
$a = $b || $c
лучше, чем
$a = $b ? $b : $c
и тем более лучше, чем
if ($b) {
$a = $b;
}
else {
$a = $c;
}
Также
$a ||= $b
короче и элегантнее, чем
unless ($a) {
$a = $b;
}
2. Сокращённая форма записи, основанная на &&
Если это не ухудшает читабельность кода, приветствуется использование сокращённой формы записи, основанной на применении логического оператора «и».
$result = $switch && $value;
Данная конструкция присваевает значение $value переменной $result только в том случае, если $switch имеет true-значение. В противном случае будет присвоено значение $switch.
А в последующих случаях более уместно использование постфиксного if
, нежели логической конструкции, основанной на &&
.
# Метод method будет вызван только тогда,когда объект $obj проинициализирован.
$result = $obj && $obj->method;
# Но лучше постфиксное условие:
$result = $obj->method if $obj;
# Функция do_something будет вызвана только
# при выполнении условий $condition1 и $condition2
$condition1 && $condition2 and do_something();
# Но лучше использовать постфиксный if,
# т. к. Сразу бросается в глаза действие, а условие чаще всего вторично:
do_something() if $condition1 && $condition2;
3. Используйте and
и or
вместо условных конструкций if
при обработке фатальных ошибок
В ряде случаях (когда при каком либо условии нужно выполнить всего один оператор) удобнее выполнять условный код с помощью and
или or
, чем громоздить блоки if
:
mkdir $tmpdir, 0700 or die "can't mkdir $tmpdir: $!";
$username = get_user_name() and print "Username: $username\n";
4. Минимизация использования циклов for
и обращений к элементам по индексу
Старайтесь избегать использование классического цикла for
с целочисленным индексом, везде, где это возможно.
В целом, старайтесь минимизировать обращение к элементам массивов по индексам.
При обработке элементов списка отдавайте предпочтение циклам foreach
, а также функциям, обрабатывающим сразу весь список сразу, таким как
grep
, map
, sort
, join
, split
и т.д.:
@foo = grep !/^P/, @bar;
@foo = map { $_ * 10 } @bar;
$_ *= 10 for @bar;
При этом не переусердствуйте: не стоит использовать map
в void-контексте, там где уместнее было бы использовать for
.
Обычно требуется обработка всех элементов массива сразу, а в этом случае удобнее
использовать циклы foreach
или функции, обрабатывающие массив целиком (см. п 4.).
В случае использования foreach
, grep
, map
элементы массива при каждой итерации предстают в виде переменной
"$_
" (или, для циклов foreach
, любой другой переменной,
какой Вы укажете), с которой работать куда удобнее, чем каждый раз обращаться
к элементам массива по индексу.
Кроме того, часто необходим доступ только к крайним элементам массива (например, идёт процесс поэлементного заполнения массива и на каждой итерации мы добавляем новый элемент).
В этом случае рекомендуется пользоваться функциями push
, pop
, shift
, unshift
.
Применение этих функций позволяет получить более простой, компактный и БЫСТРЫЙ код. Сравните:
$cnt = 0;
while (condition) {
...
$items[ $cnt++ ] = $value; # Калька с низкоуровневых языков
}
while (condition) {
...
push @items, $value; # Короче и быстрее
}
5. Использование лаконичных вариантов функций DBI
Вместо последовательности DBI вызовов prepare
/ execute
для изменения данных предпочтительнее использовать единственный вызов do
.
Вместо последовательности DBI вызовов prepare
/ execute
/ fetch_*
для выборки данных предпочтительнее использовать единственный вызов selectrow_*
/ selectall_*
/ selectcol_*
.