Случилось мне еще раз вернуться к языку Perl, но на этот раз ради простого любопытсва, после того, как я увидел кучу взрослых людей, которые просто используют его повсеместно и никому ничего не доказывают.
Начал изучение языка не с документации, как в прошлый раз, а с книги Learning Perl и не пожалел. Изложение местами напоминает художественный рассказ, встречается юмор в тему и любопытные исторические сноски.
Описание языка началось с рассказа о том, как лингвист Лари Уолл решая очередную задачу с разбором каких-то файлов-отчетов случайно написал свой язык программирования — нулевая версия перла, в 85 году, если я не ошибаюсь.
Далее по тексту следует не просто описание синтаксиса, а показывается ход мыслей создателя, почему он сделал так, а не иначе — благодаря таким отсылкам к внутреннему миру Ларри синтаксис перестаешь запоминать, но начинаешь понимать. Один из первых интересных примеров был про префиксы перед переменными: скаляр и массив:
my $calar;
my @rray;
Пока погружаешься в язык, с одной стороны узнаешь много нового о программировании вцелом, а с другой создается впечатление, что ты не программирование сейчас изучаешь, а грамматику какого-то нового для себя иностранного языка. Основное отличие перла в том, что он на самом деле является в некотором смысле естественным языком: контекстно зависимый синтаксис, возможность инверсии конструкций (перестановка слов в предложении) и самое интересное — его дальнейшее развитие именно как языка, а не как технологии.
foreach my $value (@array) {do_something ($value)} # первоначальный вариант цикла
foreach (@array) {do_something} # использование переменной $_ по умолчанию
do_something foreach @array # инверсия синтаксиса
Поясню, что я имею в виду последним утверждением: большинство языков развиваются по схожему принципу, от ограниченного функционала к более расширенному, с новыми версиями растет число функций, интерфейсов и типов данных. Так, к примеру, сначала ActionScript имел в своем наборе возможностей только интерфейс управления векторными объектами и мог запускать и останавливать ролик, потом туда добавили инструменты для создания классов, сокетов, работы с бинарными форматами данных и много чего нового. Такая же история была с PHP, который сохраняя старый запас функций, учился работать с кодировками, БД и новыми форматами данных. Языки все время усложняются, из них почти никогда ничего не выбрасывают. В результате то и дело натыкаешься на "годичные кольца".
Но совсем иначе развивался (и что интересно, развивается до сих пор) перл — он все время сжимается и сокращается, синтаксис с каждой новой версией сворачивается в более простые и универсальные конструкции. Я сказал, что перл разивался как естественный язык, потому что основные изменения касались его синтаксиса: достаточно сложные операции с массивами и строками теперь выполняются в одну строку именно благодаря этому.
2 == 4; # сравнение чисел
'foo' eq 'bar'; # сравнение строк
'foo' =~ /[a-z]+/; # сравнение с регулярным выражением
# с выходом версии 5.10 появляется унивесальный smart matching
# можно сравнивать любые типы и структуры между собой, смысл такого действия
# будет зависеть от контекста:
2 ~~ 4 or 'foo' ~~ 'bar' or 'foo' ~~ /[a-z]+/ or @arr1 ~~ @arr2 # or etc.
Интересно развивались и условия:
if (...) {...} else {...}
... if ...
if (...) {...} elsif (...) {...} else {...}
# с выходом версии 5.12 появляется given со smart matching внутри
given ($foo) {
when ('bar') {...}
when (/[a-z]+/) {...}
default {...}
}
foreach (@foo) {
when (...) {...}
default {...}
}
Контексты позволяют обходиться, например, без дополнительных функций вычисления длины массива или чтения/записи файлов:
my @a = qw(a b c d);
my $length = @a; # в контексте скаляра вычисляется длина массива
while (<~/*>) {...} # в $_ будет передаваться хендл каждого файла директории
while (<STDIN>) {...} # чтение строки из стандартного ввода
while (<>) {...} # чтение строки из файлов, переданных по параметру
# при вызове $ perl test.pm file.txt
while (<$file>) {...} # чтение строки из открытого файла
По-моему, это отличный пример того, как можно создавать универсальный и удобный инструмент, развивая только стандартные средства языка, совершенствуя его синтаксис. Кроме того, перл возрождает процедурное программирование, которое я сам считал устаревшим и неудобным — опять же благодаря своему особенному отношению к возможностям синтаксиса.
reverse sort @arr; # обратная сортировка из двух функций
chomp foreach @arr; # отрубить \n в конце каждого элемента массива
Нет никакого ада из скобочек и бесконечных вложений одних конструкций в другие, есть только простые и лаконичные синтаксические конструкции.
При всем при этом, я даже не стану описывать его внутренний язык регулярных выражений, который с переменным успехом портируется на другие языки. В Learning Perl я еще раз с нуля прочитал введение в регулярные выражения и узнал кучу новых возможностей, а за подробностями можно обратиться к отдельной книге только про регулярные выражения.
Естественно, у языка достаточно высокий порог вхождения — точно так же ни у кого не получится за один вечер выучить испанский или немецкий. Сейчас это часто является решаюшим фактором при выборе технологии — можно ли ее потом будет отдать на сопровождение индусам. Перл отдать плохим специалистам нельзя, а потому и с кадрами плохо, и слухи всякие про отcталость языка. Подобная история преследует гибкий и удобный XSLT.
Perl — интересный и уникальный язык со своей историей развития и здравыми идеями. Просто иметь о нем представление уже полезный опыт для каждого программиста.

Comments
chomp принимает LIST
ну, если sort умолчальный.
Но ведь давно уже есть use Switch :)
Но "попробовав" Perl однажды, так просто с него не слезть :)
И действительно книга Ларри просто потрясающая.
ООП в перле забавное, оно там такое голое, без сахара и держится на честном слове разработчика. Смотришь, как на экзотику.