Точка с запятой в перле необязательна, если она приходится на конец блока:
sub doit {
say 123
}
В отличие от, например, C++, где аналогичная конструкция вызовет ошибку компиляции:
int main() {
return 0
}
s.cpp: In function 'int main()':
s.cpp:3: error: expected ';' before '}' token
Различие здесь в том, чем точка с запятой является с точки зрения языка. В перле это разделитель инструкций, в C++ — признак окончания выражения.
В JavaScript ситуация еще интереснее: там точки с запятой допустимо опускать не только в конце блока, но и в конце строки:
x += id.value
alert(x)
При этом разрешено продолжать выражение на следующей строке:
x +=
id.value
alert(x)
Когда компилятор прочитывает очередную строку и не встречает точки с запятой, он делает попытку продолжить инструкцию кодом, записанным на следующей строке. Если при этом обнаружится синтаксическая ошибка, то компилятор возвращается к концу предыдущей строки и считает, что предыдущее выражение закончилось на предущей строке.
Промежуточное резюме: на C++ компилятор строг настолько, что просит явно сообщать, где заканчивается очередная порция кода, а на JavaScript допускаются вольности, но за счет дополнительных действий во время анализа кода.
В перле иногда очень соблазнительно не только опускать точку с запятой в конце блока, но и ключевое слово return в последней инструкции подпрограммы:
sub add {
my ($a, $b) = @_;
$a + $b
}
Результат выражения $a + $b — последнее значение, вычисленное в теле подпрограммы — считается результатом, который и нужно передать вызывающему коду.
Выглядит лаконично, не спорю. Но такая экономия на символах обычно оборачивается недоумением при попытках внести в код изменения.
Ситуация очень похожа на рекомендацию ставить запятую после последнего элемента при объявлении хеша:
my %x = (
alpha => 'a',
beta => 'b',
);
Перл создает в хеше ровно два элемента, но запятая помогает при добавлении новых элементов (которые часто добавляются копированием и вставкой последней строки). Этот фокус не проходит с яваскриптом: если поставить запятую после последнего элемента массива, то будет создан еще один элемент со значением undefined.
В перле отсутствие точки с запятой в конце строки может привести к тому, что ее отсутствие не будет замечено, когда после этой строки потребуется дописать новые инструкции:
sub add {
my ($a, $b) = @_;
$a + $b
warn $a;
}
Даже на время отладки не хочется искажать написанный ранее код, поэтому пропущенная точка с запятой просится в начало строки:
sub add {
my ($a, $b) = @_;
$a + $b
; warn $a;
}
Такие трюки с пропущенной запятой — один из приемов, которые малыми шажками ведут код к read-only-модели.
Например, продолжая такую идеологию возможно было бы записать функцию так:
sub add {
shift() + shift
}
Но лучше так не делать. Или только ради развлечения и изучения возможностей языка.
Комментировать