Обязательна «лесенка» с отступом в 2 пробела (half-tab). При этом запрещается в редакторе изменять размер отображаемой табуляции, например выставлять отображение табуляции в 2 пробела. Код, созданный Вами при таких настройках, будет некорректно отображаться в других редакторах с другими настройками.
После запятых и точек с запятой (если, конечно, они не расположены в конце строки) ставятся пробелы. Перед запятой и точкой с запятой пробелы не ставятся:
@a = (1, 2, 3); for (my $i = 0; $i < $count; $i++) { } |
Любые операторы/знаки операций (перечисленных в perlop, например "=", "==", "=>", "<", ">", "&&", "||" и т.п.) обязательно отделяются пробелами с обоих сторон.
В арифметических выражениях количество пробелов вокруг знаков операций можно варьировать, чтобы подчеркнуть приоритет операций. Примеры:
$a = $b * $c + $d * $e; $a = $b * $c + $d * $e; |
После любых ключевых слов языка perl, исключая Quote-Like Operators, Regexp Quote-Like Operators , а также после имён функций / методов, обязательно следует либо пробел либо скобка.
Примеры:
@foo = grep !/^#/, @bar; @foo = mygrep( qr/^F/, @bar ); |
В случае, если Вы обращаетесь к элементу массива или хэша по индексу и индексное выражение достаточно сложное, отделяйте его пробелами для улучшения удобочитаемости. Если выражение простое — пробелы не обязательны.
$a[1]; $a[ 1 + 2 + 2 + 4 * function( $a{ $b->{c} } ) ]; |
При вызове функций с аргументами, если аргументов больше одного и аргументы сложны, для улучшения визуального восприятия аргументов, лучше сделать пробелы внутри круглых скобок:
do_something_simple('abc'); # В этом случае аргументы пробелами можно не отделять do_something_comprehensive( $a[1], $b->{c}->{d}->[0]->doit(), 1, undef, 2 ); # Хорошо do_something_comprehensive($a[1], $b->{c}->{d}->[0]->doit(), 1, undef, 2); # ПЛОХО! |
После символа начала комментария («#») перед текстом самого комментария ставится пробел:
# Комментарии начинаются С ЗАГЛАВНОЙ БУКВЫ! # Вторая строка комментария |
Исключение составляют fancy comments, где допускается сливать начальный символ решётки с последующими символами:
############# MY COMMENT ############### #************** INIT ******************* |
Для того, чтобы понять, насколько хорошо отформатирован Ваш исходный текст: достаточно ли отступов, пробелов и пустых строк — попробуйте отключить подсветку синтаксиса в Вашем редакторе. Если после отключения подсветки код по-прежнему легко читаем (просмотр и анализ текста производится легко, любые конструкции легко выделяются визуально) — значит код действительно удобочитаем.
Не стоит полагаться на подсветку синтаксиса как на «костыль», скрывающий недостатки форматирования.
Левый край комментариев выравнивается точно так же, как и основной код, т.е. используется принцип "лесенки".
# Тили-тили # Трали-вали if ($cond) { # Это дело мне по силе, # Откажусь теперь едва ли. } else { # Это мы не проходили, # Это нам не задавали! } |
Ставить символы «решётки» вначале строки, если левая граница кода находится правее, не допускается.
# Тили-тили # Трали-вали if ($cond) { # ТАК ДЕЛАТЬ НЕЛЬЗЯ!!! } |
Строки желательно не оставлять слишком длинными; условное ограничение — 80-100-120 символов в строке. При необходимости строка разбивается на несколько.
Примеры допустимого разбивания конструкций:
very_long_statement if condition; if ( very_long_condition_1 && very_long_condition_2 ) { statement; } if ( .. && ... || ... ) { ... } |
Старайтесь придерживаться компактного (K&R) стиля оформления циклов и блоков ветвления: открывающая фигурная скобка находится на той же строке, что и ключевое слово «for», «if», «else», «while» и т. п.
После открывающей фигурной скобки обязателен перевод строки. Т. е. содержимое блока начинается с новой строки. Из этого правила могут быть исключения, см. п. 1.14.
Закрывающая фигурная скобка блока, состоящего из нескольких строк, должна находиться на одной вертикали с ключевым словом начинающим конструкцию.
Примеры:
if ($condition) { statement1; } else { statement2; } for (my $i = 0; $i < $count; $i++) { statement; } |
Не ставьте ключевые слова else и elsif на той же строке, что и закрывающая фигурная скобка, заканчивающая предыдущий блок. Начинайте конструкцию else / elsif с новой строки!
if ($condition) { statement1; } else { statement2; } |
Перед открывающей фигурной скобкой в блочных конструкциях всегда ставится пробел:
for (@array) { statement; } |
Однострочные блоки, состоящие из единственного оператора, могут быть помещены в одну строку вместе с открывающими и закрывающими скобками:
for (@array) { $_ *= 2; } |
Возможно, лучше в подобных случаях использовать постфиксную форму записи:
$_ *= 2 for (@array); |
В Perl символ «;» является всего лишь разделителем (а не терминатором) операторов. В результате синтаксис позволяет НЕ ставить точку с запятой после последнего оператора блока. Однако, ставьте точку с запятой всё равно, даже если у вас всего лишь один оператор в блоке.
Если точку с запятой не ставить, это может служить источником ошибок после добавления новых операторов в конец блока, т. к. на отсутствие точки с запятой после последнего оператора можно просто не обратить внимания. В результате получится неверный код:
push @a, $a print @a # Ошибка! Пропущена ";" |
Следуя этому правилу, Вы сможете избежать лишних ошибок при добавлении элементов в конец списка. Также Вам будет проще перегруппировывать элементы списков, не заботясь о расстановке запятых.
my @dwarves = ( 'Happy', 'Sleepy', 'Dopey', 'Sneezy', 'Grumpy', 'Bashful', 'Doc', ); |
Избегайте излишней пунктуации. В особенности, лишних скобок при вызове функций, или при выделении условий.
Например, опускайте круглые скобки для задания аргументов встроенных функций и функций, имеющих прототип:
m@foo = grep !/^#/, @bar; |
или при написании условия в операторе if с постфиксной записью, а также в тернарных операторах:
print "Ok" if $ok1 && $ok2; $message = $success ? "OK" : "NOT OK"; |
Только не забывайте о приоритетах операций.
Словом, стоит опустить лишние скобки там, где их отсутствие не идёт в разрез с удобочитаемостью.
Код внутри функций должен быть разделён на смысловые блоки, выполняющие определённую узкую задачу. Смысловые блоки отделяются друг от друга пустыми строками. Для дальнейшего улучшения сопровождабельности кода, добавляйте вначале каждого абзаца однострочный комментарий, объясняющий, что делает эта последовательность операторов.
sub addarray_internal { my ($var_name, $needs_quotemeta) = @_; # Запомнить оригинал... $raw .= $var_name; # Добавить экранирование спецсимволов, если необходимо... my $quotemeta = $needs_quotemeta ? q{map {quotemeta $_} } : $EMPTY_STR; # Перевести элементы переменной в строку, соединяя их с помощью "|"... my $perl5pat = qq{(??{join q{|}, $quotemeta \@{$var_name}})}; # Добавить отладочный код, если необходимо... my $type = $quotemeta ? 'literal' : 'pattern'; debug_now("Adding $var_name (as $type)"); add_debug_mesg("Trying $var_name (as $type)"); return $perl5pat; } |
Выравнивайте сходные элементы по вертикали, особенно если они достаточно короткие чтоб поместиться в одну строку:
my %wm_conts_map = ( first_name => 'iname', last_name => 'fname', email => 'email', ); $IDX = $ST_MTIME; $IDX = $ST_ATIME if $opt_u; $IDX = $ST_CTIME if $opt_c; $IDX = $ST_SIZE if $opt_s; mkdir $tmpdir, 0700 or die "can't mkdir $tmpdir: $!"; chdir($tmpdir) or die "can't chdir $tmpdir: $!"; mkdir 'tmp', 0777 or die "can't mkdir $tmpdir/tmp: $!"; |