pragmatic 25 perlpragmaticperl.com/issues/25/pragmaticperl-25-ebook.pdf · Другие...
TRANSCRIPT
pragmaticperl.com03/2015
PragmaticPerl
25
Pragmatic Perl 25
pragmaticperl.com
Выпуск 25. Март 2015
Другие выпуски и форматы журнала всегдаможно загрузить с pragmaticperl.com. С во-просами и предложениями пишите на почту[email protected].
Комментарии к каждой статье есть в html-версии. Подписаться на новые выпуски можнопо ссылке pragmaticperl.com/subscribe.
Авторы статей: Андрей Шитов, Владимир Лет-тиев, Александр Ружников
Обложка: Марко Иванык
Корректор: Андрей Шитов
Выпускающий редактор: Вячеслав Тиханов-ский
Ревизия: 2015-03-02 09:40
© «Pragmatic Perl»
Оглавление
1 От редактора. Два года жур-налу . . . . . . . . . . . . . . . 1
2 Подключение в Mojoliciousмодели для бизнес-логики . . 4
3 Мутационное тестирование . 19
4 Про переменные и сигнату-ры в Perl 6 . . . . . . . . . . . . 32
5 Модули в Perl 6 . . . . . . . . . 49
6 Обзор CPAN за февраль 2015 г. 61
7 Интервью с ВладимиромЛет-тиевым . . . . . . . . . . . . . . 73
1 От редактора. Два года журналу
Друзья! Нашему журналу исполняется двагода с первого выпуска. Поздравляем вас инас с этим событием. Подведем итоги двухлет.
За прошлый год мы выпустили без пере-рывов и почти вовремя 12 номеров, взялиинтервью у известных в Perl-сообществепрограммистов, авторов книг, организа-торов конференций. В создании журналапоучаствовали 29 авторов. Совместнымиусилиями авторов, корректоров и редакто-ров подготовили 1479 страниц текста!
Мы провели опрос, по результатам которо-го были составлены рекомендации для ав-торов. Читатели в целом оценили журналхорошо. Подписалось на рассылку по email
— 1141 человек, по rss — 194. Присоединяй-тесь!
У сайтажурнала было около 105 000 посеще-ний, из которых 45 000 были уникальными.Журнал был скачан 60 000 раз.
География (top 10):
• Россия 64 171• Украина 21 273• Беларусь 2 965• США 2 081• Нидерланды 1 408• Казахстан 1 286• Германия 1 218• Велокобритания 1 021• Израиль 907• Литва 493
Друзья, журнал ищет новых авторов. Неупускайте такой возможности! Если у васесть идеи или желание помочь, пожалуй-ста, свяжитесь с нами.
Приятного чтения.
■ Вячеслав Тихановский
2 Подключение в Mojolicious моделидля бизнес-логики
Рассмотрен вариант автоматическогоподключения классов моделей из указаннойдиректории
Mojolicious — фреймворк для написаниявеб-приложений, имеющий в своём арсе-нале много полезного функционала какпоначалу кажется, на все случаи жизни. Нокогда начинаешь с ним плотно работать ипытаться написать большое приложение,можно наткнуться на ситуацию, когданужные решения отсутствуют в базовомнаборе. Лично для меня недостатком мод-жо явилось отсутствие в нём моделей.Притом, что странно, данный функционалне реализован ни в самом моджо, ни вплагинах к нему, поиск по CPAN и в Гугле
не выявил соответствующих плагинов.
За время работы с фреймворком Catalyst япривык к MVC, и не хотелось отказыватьсяот данного принципа разработки в моджо.
Вкратце напомню, в чём суть MVC. При-ложение явно разделяется на три части:контроллер, модель и представление дан-ных. В контроллер поступают запросы отпользователя, и в них же ведётся предва-рительная обработка данных (выведениепереданных параметров, их валидация,проверка авторизации и пр.). Бизнес-логика и работа с базой данных вынесенав модель. Например, получение суммыбалланса пользователя из базы данных,услуги, подключенные у пользователя, ит.п. Полученные данные возвращаютсяобратно в контроллер и далее отобража-ются пользователю через представление
(view). Как правило, для представленияиспользуются шаблонизаторы наподобиеTemplate::Toolkit. Контроллер в данной схе-ме выступает тонкой прослойкой междупользовательским запросом, моделью ипредставлением. В самом контроллере, какправило, бизнес-логику не размещают,иначе получаются «толстые уродливыеконтроллеры», в которых функционалразмазан и плохо поддаётся тестированию.
Итак, чего хочется? Хочется моделей как вCatalyst, чтобы из контроллера можно былоделать вызовы вида:1 sub my_controller {2 my $self = shift;34 # ...5 $self−>model('ModelName')−>
model_method;6
7 # ...8 }
и чтобы фреймворк сам подгружал все мо-дели из соответствующей директории.
В моджо программисту самому предлагает-ся дописывать необходимый функционал(например, вынести в модули отдельнойдиректорией), либо писать обработкуданных и бизнес-логику прямо в контрол-лерах. Подобный подход применяется ввеб-фреймворках на других языках про-граммирования, например, laravel на php,flask на python и revel на Go.
Мне же, напомню, хотелось явного опреде-ления моделей в коде. После вдумчивогогугления, просмотра кода других разработ-чиков и длительного курения мануалов явыработал для себя реализацию моделей
в моджо, которой хочу поделиться с ваминиже.
Реализация
Итак, для создания модели делаются сле-дующие шаги (покажу на примере новогоприложения):
• Генерим mojo-приложение: mojogenerate app MyApp && cdmy_app/lib.
• Создаём необходимые файлы идиректории: touch MyApp/Model.pm && mkdir MyApp/Model &&touch MyApp/Model/Base.pm.
• Правим MyApp.pm:
1 package MyApp;23 use Mojo::Base 'Mojolicious';4 use MyApp::Model; # <−−
подключаем модуль с моделью56 sub startup {7 my $self = shift;89 #
################################################
10 # подключаем модель11 my $model = MyApp::Model−>new
(app => $self);1213 # создадим соответствующий
хелпер для вызова модели14 # из контроллеров15 $self−>helper(16 model => sub {17 my ($self,
$model_name) = @_;
18 return $model−>get_model($model_name);
19 }20 );21 #
################################################
2223 my $r = $self−>routes;2425 $r−>get('/')−>to('root#index'
);26 }2728 1;
Правим MyApp/Model.pm:1 package MyApp::Model;23 use Mojo::Loader;4 use Mojo::Base −base;
56 use Carp qw/ croak /;78 has modules => sub { {} };9
10 sub new {11 my ($class, %args) = @_;12 my $self = $class−>SUPER::new
(%args);1314 my $model_packages = Mojo::
Loader−>search('MyApp::Model');
15 for my $pm (grep { $_ ne 'MyApp::Model::Base' } @{$model_packages}) {
16 my $e = Mojo::Loader−>load($pm);
17 croak "Loading '$pm'failed: $e" if ref $e;
18 my ($basename) = $pm =~ /MyApp::Model::(.*)/;
19 $self−>modules−>{$basename} = $pm−>new(%args);
20 }21 }2223 sub get_model {24 my ($self, $model) = @_;25 return $self−>modules−>{
$model} || croak "Unknownmodel '$model'";
26 }2728 1;
Правим MyApp/Model/Base.pm:1 package MyApp::Model::Base;23 use Mojo::Base −base;45 has 'app';6
7 1;
Теперь подробнее о том, что было сделано.
В файле MyApp.pm мы создали объект клас-са MyApp::Model, которому в конструкторпередали текущий объект. Передача в кон-структор текущего объекта необходима длятого, чтобы потом из модели можно былообращаться ко всемметодам текущего клас-са.
В MyApp/Model.pm в конструкторе мынаходим все файлы в директории MyApp/Model/ используя класс Mojo::Loader иметод search. Тут необходимо уточнить,что Mojo::Loader не умеет рекурсивнообходить каталог, т.е. если директорияMyApp/Model имеет вид:1 MyApp/Model2 |_ModelFile.pm
3 |_ModelFile2.pm4 |_MoreModel5 |_MoreModel1.pm6 |_MoreModel2.pm
то Mojo::Loader−>search('MyApp::Model') проигнорирует директориюMoreModel и загрузит модули только изкорневой директории. Как вариант, мож-но дополнительно в цикле перебрать всеподдиректории в корневой директориии скормить их также Mojo::Loader длязагрузки модулей.
Далее по коду. В конструкторе модели мыподгружаем каждый найденный модульс моделью (за исключением MyApp::Model::Base, о нём дальше) и загружаемего в хеш modules. Метод get_modelвозвращает класс, соответствующий запра-шиваемому, либо падает с ошибкой.
В файле MyApp/Model/Base.pm мы указы-ваем все методы, которые будут наследо-ваться остальными моделями. Исходя изназвания становится понятно, что это ро-дительский класс для остальных модулейс моделями. Строка1 has 'app';
говорит о том, что необходимо представитьэлемент объекта1 $self−>{app}
как метод класса. Т.е. вызов $self−>app−>config равносилен $self−>{app}−>config. Это синтаксический сахар отсоздателя моджо.
Что такое app можно понять, взглянув накод модуля MyApp.pm. Это объект самоговерхнего класса MyApp.pm, который мы
передали в конструктор.
Теперь приведём пример простейшего мо-дуля с моделью, например, MyApp/Model/MyModel.pm:1 package MyApp::Model::MyModel;23 use Mojo::Base 'MyApp::Model::
Base';45 # получить все данные из конфига6 sub get_config_data {7 my $self = shift;89 return $self−>app−>config;
10 }1112 1;
Вызвать данный метод из контроллера лег-че лёгкого:
1 my $config = $self−>model('MyModel')−>get_config_data;
В данном случае будет вызван хелперmodel, определёный в методе MyApp::startup. Данный хелпер вернёт вызовметода get_model объекта класса MyApp::Model.
Ну вот и всё. Как видите, ничего особо слож-ного нет. Я надеюсь, что через некторое вре-мя у меня дойдут руки оформить это всё ввиде плагина для моджо, так как с ним впоследнее время я работаю довольно актив-но, и писать один и тот же код постоянноутомляет. По крайней мере, проект на гит-хабе под это дело уже создал :)
У кого есть вопросы, задавайте их в коммен-тариях.
Дополнительные материалы:
• Mojo documentation• Что такое helper в моджо• Mojo example apps• Пара хороших статей о моджо на хаб-ре
■ Александр Ружников
3 Мутационное тестирование
Еще один способ сделать Perl-код качествен-нее — мутировать тесты для нахождениянепротестированного кода
Мутационное тестирование — способ про-верки качества тестовых наборов путемвнесения случайных изменений в тести-руемый код. Если после таких измененийтесты все еще проходят, значит они недо-статочно качественны, т.е. не полны.
Чтобы понять, зачем это нужно и какэто проверять, рассмотрим следующийпример:1 package Temp;23 use strict;4 use warnings;
56 sub new {7 my $class = shift;8 my (%params) = @_;9
10 my $self = {};11 bless $self, $class;1213 $self−>{critical} = $params{
critical};1415 return $self;16 }1718 sub is_critical {19 my $self = shift;20 my ($temp) = @_;2122 return $temp >= $self−>{
critical};23 }2425 1;
Данный класс возвращает флаг, сигнали-зирующий о критической температуре.Тест для него был написан не очень вни-мательным программистом и выглядитследующим образом:1 use strict;2 use warnings;34 use Test::More;5 use Temp;67 my $temp = Temp−>new(critical =>
32);89 ok $temp−>is_critical(32);
1011 done_testing;
Тест явно недостаточен. Проверяется толь-ко лишь равенство критической температу-ре. Как же выявить, что тест неполный? По-
пробуем посмотреть на покрытие кода те-стами, используя Devel::Cover:1 $ PERL5OPT=−MDevel::Cover prove t
&& cover2 lib/Temp.pm
100.0n/a n/a 100.0 0.0
100.0
Покрытие 100%. Таким способоммыничегоне выявили. Неужели нельзя каким-то об-разом автоматически выявлять подобныепроблемы, без участия человека? Можно!Здесь нам и пригодится мутационноетестирование.
Задача мутационного тестирования на ос-нове исходного класса, скрипта, да вообщелюбого кода, — сгенерировать нескольковариантов, где случайным образом изме-нить операторы, ключевые слова, удалить
или добавить переменные и так далее. За-тем мутированный код запускается черезисходный набор тестов, и если тесты прохо-дят, значит они недостаточно качественныи полны.
В описанном примере при мутации опера-тор >= будет заменен, например, на <=, итесты все также будут проходить, таким об-разом выявляя свои недостатки.
На сегодняшний день для многих языковпрограммирования существуют подсоб-ные утилиты для проведения мутационно-го тестирования. Здесь же рассмотрим, какэто можно сделать в Perl.
Как отпарсить Perl
Как можно проводить мутации? Можно,конечно, использовать регулярные вы-ражения, однако на практике разбиратьPerl-код с помощью регулярных выраже-ний невозможно без высокой доли ложныхсрабатываний, ошибок и прочего. Гораздоболее надежный способ — это использоватьPPI.
Несмотря на известное выражение “Onlyperl can parse Perl” (“Только perl-интерпретаторможет отпарсить Perl-язык”), PPI работаетдовольно сносно для большинства приме-ров кода. Вот как, например, заменить вописанном выше классе оператор >= на <=:1 my $ppi = PPI::Document−>new('
Temp.pm');23 if (my $operators = $ppi−>find('
PPI::Token::Operator')) {4 foreach my $operator (
@$operators) {5 if ($operator−>content eq
'>=') {6 $operator−>
set_content('<=');78 $ppi−>save('Temp.pm.
mutant');9 }
10 }11 }
Т.е. находим все операторы (токен PPI::Token::Operator), затем нужныйзаменяем на <= и сохраняем мутантапод новым именем. Можно проводитьи несколько мутаций, таким образомвыявляя практически непроявляющиесяошибки.
Для мутационного тестирования на CPANесть модуль Devel::Mutator. Для генера-ции мутантов необходимо указать, какиефайлы мутировать:1 $ mutator mutate −r lib/*
По умолчанию все мутанты складываютсяв директорию mutants. Ключ−r для рекур-сивного нахождения модулей.
Для запуска же самих тестов выполняетсякоманда test:1 $ mutator test
Это команда для каждого мутанта издиректории mutants запускает тестыиз текущей директории. По умолчанию,запускается prove −l t, но это можнопереопределить с помощью опции −−command. Успешность или неуспешность
тестов проверяется по значению $?. Т.е.если вы используете нестандартные тесто-вые модули, достаточно делать exit(0) вслучае успеха или exit(255) или любоедругое значение при неудаче.
Во время выполнения тестов на экран вы-водится текущий мутант и статус выполне-ния тестирования, где ok означает, что те-сты не проходят, а not ok — наоборот. На-пример:1 $ mutator test2 (1/10) ./mutants/49606d6...009
cd7a2/MyClass.pm ... ok3 (2/10) ./mutants/3f9577f...3
fd5f5b9/MyClass.pm ... not ok4 (3/10) ./mutants/a7c40ad...
f05df2e4/MyClass.pm ... not ok5 (4/10) ./mutants/514abf0...8401
c2f3/MyClass.pm ... not ok6 ...
Еслимутант был запущен неуспешно, мож-но просто посмотреть, что было изменено икак это повлияло на тесты:1 diff lib/MyClass.pm mutants/49606
d6bcaaf550b6cf76abf009cd7a2/MyClass.pm
Из diff можно понять правильно ли былавыполнена мутация, стоит ли обращать наэто внимание. diff может показываться иавтоматически, если указать опции −v, такможно сразу видеть, где проблема:1 $ mutator test −v2 (1/10) ./mutants/3
f9577f3d44ac20732b6340d3fd5f5b9/MyClass.pm ... not ok
3 628c6284 < my @related = @_ == 1 ? ref
$_[0] eq 'ARRAY' ? @{$_[0]} :($_[0]) : ({@_});
5 −−−
6 > my @related = @_ != 1 ? ref$_[0] eq 'ARRAY' ? @{$_[0]} :($_[0]) : ({@_});
После выполнения всех тестов выводитсяобщий результат. Например:1 Result: FAIL (31/38)
или1 Result: PASS
Таким образом с помощью модуля Devel::Mutator можно протестировать сами те-сты и понять, как их можно улучшить, темсамым повысив качество программы в це-лом.
Недостатки
Существенным недостатком мутацион-ного тестирования является возможностьпосле мутации получить эквивалентнуюпрограмму. В этом случае тесты будутпроходить, и произойдет ложное сраба-тывание. Нахождение эквивалентныхпрограмм чрезвычайно сложно и на дан-ный момент нерешаемо. Есть несколькостратегий борьбы с ложными срабаты-ваниями, написаны несколько десятковтехнических статей, но универсальноерешение так и не предложено.
Еще одним недостатком является веро-ятность создания бесконечных циклов.Для борьбы с этим в Devel::Mutatorтесты запускаются с timeout, который поумолчанию равен 10 секундам.
■ Вячеслав Тихановский
4 Про переменные и сигнатуры в Perl 6
В этой статье описаны интересные синтак-сические возможности Perl 6, о которых небыло упомянуто в прошлый раз
Обновитесь
21 февраля появился релиз Rakudo Star2015.02. Одновременно объявлено, что этопоследний релиз с поддержкой Parrot.Дальнейшая разработка будет вестись ис-ключительно под виртуальную машинуMoarVM.
Лексические переменные
Лексические переменные в Perl 6 ведутсебя так, как и должны :-) Если попытатьсяиспользовать пременную вне блока, в ко-тором она определена, возникнет ошибка.В Perl 5 ошибка возникнет лишь при нали-чии use strict или при указании версии,в которой strict заработает сам, напри-мер: use v5.12. В Perl 6 все работает сразу,и при попытке обратиться к переменнойвне области ее видимости появится ошибкаVariable '$x' is not declared.1 {2 my $x = 42;3 say $x; # OK4 }56 #say $x; # Не OK
Лексические переменные, тем не менее,возможно удачно использовать в замы-каниях. В следующем примере функцияseq() возвращает блок, в котором исполь-зуется переменная, определенная внутрифункции:1 sub seq($init) {2 my $c = $init;34 return {$c++};5 }
После вызова функции эта переменнаяне только не исчезнет, но и сохранитсвое значение, что хорошо видно припоследующих вызовах:1 my $a = seq(1);23 say $a(); # 14 say $a(); # 25 say $a(); # 3
Возможно создать две независимые копиилокальной переменной:1 my $a = seq(1);2 my $b = seq(42);34 say $a(); # 15 say $a(); # 26 say $b(); # 427 say $a(); # 38 say $b(); # 43
state-переменные
Отдельно нужно упомянуть state-переменные. Они появились в Perl 5.10 иработают так же, как и в Perl 6. Переменная,объявленная с ключевым словом stateвнутри функции, инициализируется припервом вызове и сохраняет значение при
повторных обращениях к функции.
При этом нужно понимать, что создаетсядействительно один-единственный экзем-пляр переменной. Если вернуться к приме-ру со счетчиком и использовать там stateвместо my, то возвращаемое замыкание бу-дет обращаться к одной и той же перемен-ной.1 sub seq($init) {2 state $c = $init;34 return {$c++};5 }
Сколько бы не создавалось счетчиков:1 my $a = seq(1);2 my $b = seq(42);
Все они будут являться одним и тем же:
1 say $a(); # 12 say $a(); # 23 say $b(); # 34 say $a(); # 45 say $b(); # 5
Динамические переменные
Область видимости динамических пере-менных, в отличие от лексических, вычис-ляется в тот момент, когда к переменнойпроисходит обращение. Поэтому разныевызовы одного и того же кода могут датьразные результаты.
Динамические переменные помечаютсявторым сигилом (твигилом) * (с намекомна wildcard).
В следующем примере функция echo() пе-чатает динамическую переменную $*var,которая не только не определена в самойфункции echo(), но и не является глобаль-ной переменной в программе. Тем не ме-нее, имя резолвится при вызове из другихфункций, в каждой из которых есть своя пе-ременная с таким именем:1 sub alpha {2 my $*var = 'Alpha';3 echo();4 }56 sub beta {7 my $*var = 'Beta';8 echo();9 }
1011 sub echo() {12 say $*var;13 }14
15 alpha(); # Alpha16 beta(); # Beta
Анонимные блоки
В Perl 6 есть понятие arrow blocks (илиpointy blocks) — это такие анонимныеблоки-замыкания, которые возвращаютссылку на функцию и могут приниматьаргументы.
Синтаксически они снабжаются стрелкой−>, за которой следует список аргументови блок кода:1 my $cube = −> $x {$x ** 3};2 say $cube(3); # 27
Здесь сначала создается блок {$x ** 3},принимающий один аргумент $x, а за-
тем делается вызов, аналогичный вызовуфункции через указатель на нее: $cube(3).
Такие блоки со стрелкой удобно использо-вать в циклах:1 for 1..10 −> $c {2 say $c;3 }
Фактически, for здесь принимает спи-сок 1..10 и блок кода с аргументом $c,хотя сначала может показаться, что этаконструкция — синтаксис для циклов. Вследующем разделе мы вернемся к этомупримеру, но уже без использования явнойпеременной (и поэтому без стрелки).
Список аргументов вполне может состоятьи более чем из одного элемента:1 my $pow = −> $x, $p {$x ** $p};2 say $pow(2, 15); # 32768
То же самое применимо и к спискам:1 for 0..9 −> $i, $j {2 say $i + $j;3 }
В этом случае за один проход цикл бу-дет поглощать сразу по два значения.Тело цикла отработает пять раз, печатаяпопарно сумму соседних цифр: 1, 5, 9 и т.д.
Плейсхолдеры
При создании анонимного блока кода, да-же такого, который будет принимать аргу-менты, объявлять их необязательно. Perl 6разрешает сразу использовать их подобнопредопределенным переменным $a и $b вPerl 5.
В Perl 6 такие переменные должны бытьснабжены твигилом ^, а порядок формаль-ных аргументов будет соответствоватьалфавитному порядку.1 my $pow = {$^x ** $^y};2 say $pow(3, 4); # 81
Фактические значения 3 и 4 окажутся, соот-ветственно, в переменных $^x и $^y.
А теперь вернемся к циклу и перепишемего тело без использования явных аргумен-тов:1 for 0..9 {2 say $^n2, $^n1;3 }
Обратите внимание, что, во-первых, блоккода начинается сразу без предваряющейего стрелки, а переменные $^n1 и $^n2
упоминаются в коде не в алфавитном по-рядке, но при этом получают правильныезначения, как если бы они были указаны всигнатуре функции в виде ($n1, $n2).
Наконец, плейсхолдеры могут быть име-нованными, вся разница в использованиивнутри блока кода заключается в твигиле— теперь это двоеточие ::1 my $pow = {$:base ** $:exp};2 say $pow(:base(25), :exp(2)); #
625
Порядок значений при вызове функции те-перь не имеет значения. Следующий вызоввернет тот же результат:1 say $pow(:exp(2), :base(25)); #
625
Переопределение функций
Ключевое слово multi позволяет опреде-лить несколько функций с одним именем,которые различаются списком своих аргу-ментов (сигнатурой). В Perl 6 аргументыфункций указывают сразу в заголовке, при-чем, как и обычные переменные, аргумен-ты могут быть типизированы (собственно,без указания типа мультифункции теряютсмысл).1 multi sub twice(Int $x) {2 return $x * 2;3 }45 multi sub twice(Str $s) {6 return "$s, $s";7 }89 say twice(42); # 84
10 say twice("hi"); # hi, hi
Работа этого примера довольно очевидна:когда передано целочисленное значение,вызывается twice(Int), а когда строка —twice(Str).
Переопределение с подтипами
Еще более интересное переопределениеможно сделать, использовав подтипы.Подтипы в Perl 6 создаются с помощьюключевого слова subset. На основе одногоиз существующих типов возможно создатьболее узкий тип, допустимые значениякоторого будут проверяться условием,описанным в определении подтипа.
В следующем примере созданы два подти-па: для четных и нечетных целых чисел.Условие отбора явно определено в блокепосле ключевого слова where.
Далее объявлены и определены две функ-ции с одним именем testnum, но с агру-ментами разных типов.1 subset Odd of Int where {$^n % 2
== 1};2 subset Even of Int where {$^n % 2
== 0};34 multi sub testnum(Odd $x) {5 say "$x is odd";6 }78 multi sub testnum(Even $x) {9 say "$x is even";
10 }
Теперь при вызове функции с именемtestnum будет выбрана одна из двух:testnum(Even) для четных чисел иtestnum(Odd) для нечетных:1 for 1..4 −> $x {
2 testnum($x);3 }
Программа напечатает ожидаемую после-довательность строк, что говорит о том,что Perl 6 выбрал правильный вариантфункции, используя правила, заданныедля подтипов Odd и Even.1 1 is odd2 2 is even3 3 is odd4 4 is even
Продолжение следует
В этом номере журнала вас еще ждет статьяо модулях в Perl 6, а в следующем выпус-ке читайте о промисах (promises) и подроб-ный рассаказ о том, как работать с грамма-
тиками (grammar).
■ Андрей Шитов
5 Модули в Perl 6
Краткий обзор основныхмоментов, которыеполезно знать при работе с модулями в Perl6
Тем, кто знаком с модулями в Perl 5, без тру-да разберутся с тем, как использовать их вPerl 6. Тем не менее, есть несколько важныхотличий, которые необходимо знать передначалом работы.
Модули хранятся в файлах с тем же рас-ширением .pm. Точно так же организуетсяиерархия: модуль X::Y компилятор будетискать в файле X/Y.pm в одном из пред-определенных каталогов или в каталоге,указанном в опции −I при запуске изкомандной строки.
В теории, имена модулей не обязаны бытьпривязаны к файлам (а на практике сейчасимя модуля, указанное в самом модуле,похоже, вообще не используется). Однакопока про это, видимо, лучше не думать.Еще одна интересная особенность, а имен-но, возможность хранить и подключатьодин и тот же модуль, но разных версий,пока в Rakudo не реализована.
module
Модуль объявляется ключевым словомmodule, за которым следует название. Воз-можны два варианта. Объявление можетбыть в виде директивы в начале файла, ивесь остаток файла будет телом модуля:1 module X;2
3 sub x() {4 say "X::x()";5 }
Второй вариант — поместить тело модуля вблок:1 module X {2 sub x() {3 say "X::x()";4 }5 }
export
Переменные (my, our) и функции (sub),определяемые внутри модуля, по умолча-нию не видны за его пределами. Для того,чтобы экспортировать имя, необходимоуказать свойство (trait) is export:
1 module X;23 sub x() is export {4 say "X::x()";5 }
Это все, что требуется для того, чтобыфункцией x() удалось воспользоваться впрограмме, которая будет использовать мо-дуль. Никаких многословных конструкцийи манипулирования массивами @EXPORT и@EXPORT_OK больше не требуется.
use
Подключение модуля — простая операцияс помощью ключевого слова use.
Сначала создаем файл Greet.pm:
1 module Greet;23 sub hey($name) is export {4 say "Hey, $name!";5 }
А затем используем его:1 use Greet;23 hey("you"); # Hey, you!
Точно так же все работает, если имя модуляболее сложное. В этом случае все импорти-руемые имена оказываются в текущей об-ласти видимости.
Файл Greet/Polite.pm с модулем Greet::Polite:1 module Greet::Polite {2 sub hello($name) is export {3 say "Hello, $name!";
4 }5 }
И программа, его использующая:1 use Greet;2 use Greet::Polite;34 hey("you"); # функция из модуля
Greet5 hello("Mr. X"); # из Greet::
Polite
import
Ключевое слово use автоматически вы-полняет импорт имен из подключаемогомодуля. Однако, если модуль определенв текущем файле в лексической областивидимости (обратите внимание, что мож-
но указать модуль локальным, написавmy module), автоматический импорт непроизойдет, и придется сделать его явно:1 my module M {2 sub f($x) is export {3 return $x;4 }5 }67 import M;89 say f(42);
Без принудительного импорта (importM;) обращение к функции f() из модуляприведет к ошибке. Причем импорту под-вергнутся только имена, помеченные наэкспорт конструкцией is export.
Обратите внимание, что импорт проис-ходит при компиляции, поэтому имена
станут доступны в программе даже вышестроки про импорт:1 my module M {2 . . .3 }45 say f(1);6 import M;7 say f(2);
need
Если же возникнет необходимость простозагрузить модуль, но ничего из него не им-портировать, следует воспользоваться клю-чевым словом need.
Создаем модуль N с методом n() (метод со-здан как our—это важно, но без is export
— а это не так важно):1 module N;23 our sub n() {4 say "N::n()";5 }
И теперь указываем, что нужен этот мо-дуль, а потом напрямую обращаемся к егометоду:1 need N;23 N::n();
Последовательность use M; import M;(именно в таком порядке) аналогичнаодному use M;.
require
Ключевое слово require позволяет загру-зить модуль не во время компиляции (какэто делает use), а во время исполнения.
Для примера — модуль с единственнойфункцией, возвращающей сумму передан-ных ей аргументов:1 module Math;23 our sub sum(*@a) {4 return [+] @a;5 }
(Звездочка в *@a нужна, чтобы Perl свернулвсе аргументы в один массив, и можно бы-ло бы написать sum(1, 2, 3). Без звездоч-ки это станет синтаксической ошибкой, по-скольку метод будет ожидать массив, а не
три скаляра.)
Теперь подключаем модуль с помощьюrequire и вызываем функцию:1 require Math;23 say Math::sum(24..42); # 627
Если попытаться вызвать Math::sum()до require, программа не сможет найтинужное имя. При этом импортироватьметод, написав import Math;, тоже неполучится, поскольку импорт происходитна этапе компиляции, то есть до того, какrequire загрузит модуль.
Заключение
Для удобства, вот список ключевых словPerl 6, которые потребуются при работе смодулями:
• use—загрузка и импорт на этапе ком-пиляции;
• need— загрузка без импорта на этапекомпиляции;
• import — импорт имен из загружен-ного модуля на этапе компиляции;
• require — загрузка без импорта вовремя исполнения.
■ Андрей Шитов
6 Обзор CPAN за февраль 2015 г.
Рубрика с обзором интересных новинок CPANза прошедший месяц.
Статистика
• Новых дистрибутивов — 202• Новых выпусков — 815
Новые модули
Crypt::U2F::Server
Модуль Crypt::U2F::Server являетсяобёрткой к C-библиотеке libu2f-server. Мо-
дуль реализует серверную часть протоколаU2F, предназначенного для универсальнойреализации двухфакторной аутентифика-ции, когда пользователь помимо вводапароля в браузере использует ещё физи-ческое устройство (например, USB-донгл),которое доступно браузеру через специаль-ное Javascript API.
Plack::Middleware::Antibot
Antibot — это набор фильтров для PSGI-приложений, которые позволяют боротьсяс отправкой форм роботами:
• FakeField — проверка, что было от-правлено скрытое поле;
• Static — проверка, что был загру-жен статический файл (например,
css-стили) до отправки формы;• TextCapcha — проверка, что была пра-вильно решена текстовая капча;
• TooFast — проверка, что форма былаотправлена очень быстро;
• TooSlow — проверка, что форма былаотправлена через большой интервалвремени.
Inline::Perl6
Inline::Perl6, как следует из названия,позволяет выполнять из Perl 5 код на язы-ке Perl 6, а также загружать модули и вы-полнять методы объектов Perl 6. Для рабо-ты модуля требуется установить Rakudo свключённым бекендом MoarVM.
Promises6
Promises6 — довольно любопытная реали-зация спецификации Promises/A+, предо-ставляющая синтаксис обещаний в соот-ветствии со спецификацией ECMAScript 6.Модуль требует для работы Perl не ниже5.20.0.
AnyEvent::TLS::SNI
AnyEvent::TLS::SNI — это модуль, кото-рый добавляет поддержку TLS-расширенияSNI в AnyEvent::TLS. Указав параметрhost_name, можно задать имя сервера, ккоторому будет производиться подключе-ние. Поддержка SNI работает только длястороны клиента.1 use AnyEvent::HTTP;
2 use AnyEvent::TLS::SNI;34 AnyEvent::HTTP::http_get5 'https://www.goggle.com/',6 tls_ctx => {7 verify => 1,8 verify_peername => 'https
',9 host_name => 'www.google.
com'10 },11 ...
Обновлённые модули
Gtk2 1.2495
Обновление Perl-интерфейса к библио-теке Gtk2 вышло в конце января 2015,
но только в феврале вендоры обратиливнимание, что исправленная ошибка снекорректным управлением памятью вGtk2::Gdk::Display::list_devicesможет потенциально быть использованадля выполнения произвольного кода. Всемпользователям рекомендуется обновиться.
perl 5.20.2
Вышел корректирующий релиз стабиль-ной версии Perl 5.20.2.
• Обновлён модуль Data::Dumper,в котором исправлена проблемаCVE-2014-4330, приводящая к рекур-сии при дампе глубоко вложенныхструктур данных.
• Исправлен крах в PerlIO::Sacalarпри задании файловой позиции запределами скаляра.
• Появился новыйдокумент perlunicook,который содержит исчерпывающуюинформацию о работе с Юникодом вPerl.
• Восстановлена работоспособностьсборки на платформах IRIX и Tru64.
• Исправлены несколько ошибок assertв отладочных сборках Perl.
• Исправлен крах при вызове gmtime() спараметром NaN.
• Исправлено переполнение буфера икрах при компиляции определённыхшаблонов в регулярных выражениях.
• Устранена утечка памяти в некоторыхрегулярных выражениях, появившая-ся в Perl 5.20.1.
Role::Tiny 2.000000
Вышел второй мажорный релиз модулядля создания классов-ролей Role::Tiny.Основное несовместимое изменение —теперь Role::Tiny не делает предупре-ждения фатальными для классов-ролей,созданных с его помощью. Прагмы strictи warnings по-прежнему включены.
strictures 2.000000
Вслед за Roly::Tiny новая версия прагмыstrictures отказывается от полной фата-лизации предупреждений. Следующие ви-ды предупреждений больше не вызываютаварийное завершение работы:
• exec
• recursion• internal• malloc• newline• experimental• deprecated• portable
Mojolicious 6.0
Выпущен шестой мажорный релиз веб-фреймворкаMojolicious с кодовымназвани-ем «Clinking Beer Mugs» (звенящие пивныекружки). Вопреки традиции, разработчикине стали ждать мая (последние мажорныерелизы выпускались с промежутком око-ло одного года). Удалён внушительныйсписок устаревших методов, переимено-вано множество других методов. Будьте
внимательны при обновлении.
Plack 1.0034
В новом релизе «суперклея» для веб-фреймворков Plack исправлена проблемав безопасности при использовании Plack::App::File на платформе Win32. Делов том, что в некоторых версиях Windowsвозможно использование больше двухточек в фрагменте пути для перехода ввышестоящие каталоги.
Compress::Bzip2 2.22
Вышел новый релиз обёртки к библиоте-ке сжатия Bzip2. Новая версия содержитисправление крупной утечки памяти,
возникавшей при декомпрессии.
Perl::Critic 1.124
Новый релиз модуля для проверкиисходного Perl-кода на соответствиепринятым стандартам Perl::Critic
содержит обновление для политикиProhibitUnusedPrivateSubroutines(запрет на неиспользуемые приватныеподпрограммы), в которой появиласьвозможность задать исключение длянекоторых файлов с помощью опцииskip_when_using, если они используютопределённый модуль. Это может быть по-лезно для классов-ролей, где определённыеприватные методы могут использоваться вклассах, использующих эту роль.
Кроме того, политики RequireUseStrict
и RequireUseWarnings теперь учиты-вают, что Moose, Moo, Mouse, Dancer,Mojolicious и некоторые другие модулиавтоматически включают прагмы strict иwarnings.
■ Владимир Леттиев
7 Интервью с Владимиром Леттиевым
Владимир Леттиев (crux) — постоянный ав-тор журнала, модулей на CPAN, основательperlnews.ru
Как и когда научился программировать?
Все проходили основы программированияна уроках информатики в школе. Когда яучился в школе, у нас стоял класс Корветов.Нас учили рисовать на бумажке блок-схемы алгоритмов, а потом реализовыватьих на Бейсике. Для меня компьютерывсегда воспринимались как чудо техникии прогресса, о которых я ещё вчера читалв фантастических рассказах, и вот ониуже есть в школах и даже в продаже вмагазинах электроники.
Классе в 7-м у меня появился мой первыйкомпьютер Дельта-С (клон ZX Spectrum).Там загружался сразу REPL с Бейсиком,поэтому поневоле любой пользователькомпьютера начинал программировать.Сначала я только играл в игры. Подав-ляющее число игр имело графическуюзаставку, на которой красовалась подпись«Cracked by Bill Gilbert». Мне тоже захо-телось крякать игры. Где-то за 4 месяцая успел купить и зачитать до дыр кни-ги по бейсику и ассемблеру Z80. Первойвзломанной игрой оказалась игрушка«River Rescue», где я, исследуя дизассем-бированный код, нашёл инструкцию подекременту счётчика жизней и заменилего пустой операцией. Потом по всемправилам оформил бейсик-загручик, по-местив код на строку 0 и закрыв его отвзгляда трюком с цветом фона. Попра-вил в графическом редакторе заставку на
«Cracked by Vladimir Lettiev» и записална кассету. Вскоре компьютер сгорел отразряда статического электричества, и наэтом карьера юного хакера оборвалась…
Какой редактор используешь?
Сейчас я использую Vim. Как и многиея был в шоке от первого знакомства с vi.Какая-то команда, запущенная в рутовомшелле открыла мне конфигурационныйфайл в этом редакторе. Оно пищало, ми-гало и запортило мне конфиг, преждечем я смог убить его kill’ом в соседнемтерминале.
Сначала редактировал в mcedit, так как онбыл похож на Far, который я использовалпод Windows. Пробовал nano, joe, но потомвсё-таки сел и изучил vim. И вот лет 10 ис-пользую только vim. Из плагинов исполь-
зую только Nerdtree, из тем предпочитаюdesert или wombat256mod.
Доводилось также сделать целый проектв Padre IDE. Адаптировал своё поведениетак, чтобы он не падал и, в принципе,был доволен им. Но, в любом случае, GUI-инструменты тяжело использовать черезssh-соединение, поэтому удобнее vim врядли что-то можно придумать.
Как и когда познакомился с Perl?
Кажется это был 2002 год. После окончанияуниверситета я остался там работать си-садмином и заодно учился в аспирантуре.Одной из первых задач, которая возник-ла передо мной, стало создание учётаинтернет-трафика пользователей. Мы ис-пользовали прокси-сервер Squid, и нужнобыло распарсить лог и выполнить расчёты.
Я скопировал файл в несколько гигабайтна свой компьютер. В университете мыизучали Паскаль, поэтому я написал наПаскале программу, проверил её на парестрочек лога, а потом запустил обработкувсего файла. После 15 минут ожидания яподумал, что что-то тут не так. Мой колле-га, который в то время писал cgi-скриптыдля веб-сайта университета, посоветовалпопробовать распарсить лог Перлом, т.к. онздорово подходит для работы с текстовымифайлами.
Я взглянул на пример кода и был непри-ятно удивлён, что для переменных ис-пользовалась закорючка $, почти какстроковые переменные в древнем БейсикеZX Spectrum. Но, тем не менее, я изучилсинтаксис по образцу какой-то готовойпрограммы, слепил простой цикл, кото-рый построчно читал файл, сплитил строку
и проводил суммирование. Запустил про-грамму и подумал, чем бы заняться, покаона работает, но каково было моё удив-ление, когда программа завершилась всчитанные секунды. Это был шок. С техпор использую Perl для любых задач снеизменным успехом.
С какими другими языками интересноработать?
Javascript. Это язык фронтенда, и его при-дётся изучить в любом случае, если выпишете для веба. Jquery даже делает егонемного похожим на Perl (что не удиви-тельно, т.к. создатель фреймворка былперловиком).
Язык С прекрасен. Он позволяет писатьбыстрые XS-подпрограммы для Perl.
Что, по-твоему, является самым боль-шим преимуществом Perl?
Perl позволяет очень быстро прототипиро-вать программы. Можно быстро начать пи-сать код, потом постепенно трансформиро-вать программу, разнося код по модулям/-методам, когда кодовая база начнёт расти.
Как-то я дорабатывал реализацию одногосетевого протокола на C, и это занялоуйму времени, особенно на отладке. Потомпередо мной встала задача обрабатыватьполучаемые данные прикладного уровняи записывать их в СУБД. Это уже явнотребовало языка более высокого уровня.Я за пару недель переписал реализациюпротокола на чистом Перле в отдельныймодуль и продолжил реализовывать ло-гику приложения. Уровень сложности ивремя разработки при переходе снизились
на порядок.
Ещё Perl универсален. На нём можно пи-сать короткие однострочники, скрипты,модули и огромные проекты. Функцио-нальный стиль, ООП, DSL — Perl можноадаптировать под любой стиль програм-мирования. Perl позволяет менять свойсинтаксис, что позволяет на базе Perlстроить надстройки. Посмотрите на Rex —это отличный пример как можно писатьсжатые сценарии на языке более высокогоуровня на основе Perl.
Что, по-твоему, является самой важнойособенностью языков будущего?
Период полураспада. Мне кажется, что всеязыки будущего будут появляться и исче-зать. Вечным будет только C, так как на нёми будут писать новые языки.
Что думаешь о будущем Perl?
Я смотрю на индекс TIOBE и особо не вол-нуюсь за будущее Perl. Perl есть везде. Налюбой платформе, в дистрибутиве любойюниксподобной системы его всегда можнобудет найти.
Perl по-настоящему свободный проекти принадлежит сообществу. Нет однойкомпании, узурпирующей направлениеразвития. Сообщество очень внимательнои дружелюбно к новичкам. Любой человекможет влиться в разработку и получитьмаксимальную поддержку. Perl имеет чёт-кий план регулярных релизов и здоровуюротацию ответственных за релизы. Такаяорганизация даёт +100500 к Viability.
Мне бы очень хотелось увидеть в буду-щем улучшенную организацию CPAN.
Мне кажется, что очень не хватает своегоGPG-сервера ключей для CPAN-авторов,которыми бы можно было подписыватьрелизы.
Просто напрашивается наличие аналогасервиса travis-ci, заточенного под Perl.Как обходной вариант есть специальныйхелпер, но если бы удалось создать специа-лизированную систему, которая объединитразрозненные системы Perl QA cpantesters,coverage и другие метрики исходного кода,то это было бы просто фантастикой.
Почему пишешь статьи для PragmaticPerl? Откуда берешь идеи?
Однажды я написал статью по настройкеPostfix и LDAP и опубликовал её на одномресурсе. Через полгода я по этой статьекак в первый раз настраивал новый сервер.
Тогда же я и осознал, что любые действиянеобходимо записывать, т.к. память этосамая ненадёжная штука.
Когда начал писать статьи для PragmaticPerl я понял, что можно изучать новыевещи, до которых никак не доходили руки,а статья — это отличный повод, а заодно ишпаргалка на будущее. Так, например, яразбирался с DBIx::Class, который бы ни вжизни по другому бы не изучил. Поэтомуя всем советую, если есть желание что-товыучить, то учите и параллельно пишитеконспект. Из конспекта получится хоро-шая статья, которую можно опубликоватьи получить плюс в карму. Все ваши ошиб-ки подметят и поправят — это уже избавитвас от прохода по граблям. Win-Win.
Что касается источников идей, то их два.Первый — это публикации в блогах, но-
востях, рассылках. Если проскакиваеткакая-то интересная тема, я могу сделатьпометку и развить её в статью. Второйисточник — CPAN. Готовя обзор CPAN,я просматриваю список из порядка 1000модулей с их описанием и изменениями.Какой-то модуль или что-то, связанное сним может стать предметом для статьи.
Чем так заинтересовал HTTP2, что даженаписал реализацию Protocol::HTTP2? Накакой стадиинаходится этотмодуль?Чтотакое Shuvgey?
В начале 2014 года я прочитал книжкуIlya Grigorik «High-Performance BrowserNetworking». Там в частности рассказыва-ли о протоколе HTTP2, который был созданна основе протокола SPDY от Google. Я ираньше слышал о нём, но теперь прочитало том, как он устроен. Это показалось мне
интересным и я подписался на рассылкуietf-http-wg, в которой обсуждался черно-вик стандарта нового протокола HTTP2.Довольно известные в мире веба людипредлагали новые фичи, делились своиммнением, звучали и критические отзывы,но в целом дискуссия была продуктивной.
Вскоре я уже знал про все существующиереализации и видел, что одна из существу-ющих реализаций на Perl’е уже безнадёжноустарела (по факту она толком и не работа-ла). Взглянув на код я понял, что там идётпривязка к IO::Async, а мне было интерес-но получить что-то работающее без привяз-ки к конкретным событийным фреймвор-кам. Так и началась работа над Protocol::HTTP2.
Мне очень понравился интерфейс Protocol::WebSocket, я взял его как основу, но
потом даже ещё больше упростил. Первыйработающий релиз Protocol::HTTP2вышел уже в мае 2014 года, где был ре-ализован 12-й черновик спецификациипротокола. После этого спецификацияменялась уже только в сторону упрощения:с каждым новым черновиком я простоудалял куски кода.
Сейчас работа над спецификацией HTTP2официально завершена. Вот уже на дняхожидается официальный номер RFC, послечего начнётся, нет, не правильно, про-должится его экспансия в веб. Вот вампростой факт: Firefox 35 по умолчаниюподдерживает http2 (черновик 14), за месяцего функционирования обнаружили, что9% соединений к сайтам происходило поhttp2. Это говорит о том, что в отличиеот ipv6, http2 довольно быстро станетдоминирующим протоколом веба.
Protocol::HTTP2 в целом работоспо-собен, там есть несколько некритичныхнедоделок (например, приоритеты пото-ков), которые можно будет закрыть, кактолько на них появится минимальныйспрос.
В качестве примера реализации веб-сервера на основе Protocol::HTTP2 ясоздал Shuvgey — асинхронный однопоточ-ный PSGI веб-сервер на основе AnyEventс поддержкой протокола http2. Он похожна Twiggy, только работает с http2 и можетиспользовать TLS. Кстати, сайт проектакрутится именно на шувгее, что также даётвам возможность оценить работоспособ-ность серверной реализации http2. Чтобыего увидеть вам потребуется Firefox 35 илиChrome 40.
Вообще, Шувгей — это собирательное на-
звание нечистой силы у коми-зырян икоми-пермяков. Материализуется в видесильного ветра, вихря. Это название мнепоказалось интересным, своеобразныйответ питоновскому Торнадо, а такжедань карго-культу странных названий изнационального фольклора.
Как возникла идея perlnews.ru? Как дела спосещаемостью, какие дальнейшие пла-ны?
«Pragmatic Perl» — это отличное место,чтобы опубликовать уникальную статьюс примерами кода и какими-то важнымирезультатами. Но переводные материалы,короткие новости уже выходят за рамкиформата. Персональный блог тоже плохоеместо для подобных вещей, так как еслипост о том, как вчера стоял в очереди врегистратуру поликлиники, соседствует с
новостью о том, что вышел новый Perl, итам такие-то улучшения, то это выглядитдико. Соответственно, требуется отдель-ный обезличенный тематический ресурс,специализирующийся на новостях.
Идея возникла в конце января, сайт зарабо-тал 2 февраля, 3 февраля его здорово про-пиарили на форуме и в рассылке PragmaticPerl, что дало 159 посещений 122 пользова-телей. Сейчас в среднем около 45 сеансовв день. Примерно 40 подписчиков по RSS.Треть посетителей приходит по ссылкам изтвиттера, ещё треть, по всей видимости, до-бавила ресурс в закладки.
По статистике около 62% посещений изРоссии, 13% Украина, 3,5% Беларусь, такженемного Нидерланды, США, Германия,Таиланд. После того, как был опубликованпересказ интервью Рикардо Сигнеса под-
касту rebuild.fm, пост заметил Миягава инаписал в твиттере, что ему понравилось,прочитал его через Google Translate. Этовылилось в 23 хита из Японии, так что орусскоязычном новостном ресурсе о Perlузнали и в Японии.
В планах пока ничего экстраординарного.Думаю сделать опрос, чтобы выяснить, ка-кие темы более интересны читателям, что-бы скорректировать приоритеты. Отвечатьможно в комментариях к этому интервью :)
Какможнонаписатьновостьна perlnews.ru?
Думаю, что ресурс здорово выиграет, еслина нём появится больше новостей от дру-гих авторов. Для этого потребуется лишьнемного навыков работы с github.
Исходный код сайта доступен на github –
perlnews.ru. Из данного репозитория с по-мощью Statocles генерируется статическийсайт.
Чтобы добавить свою новость, исправитьопечатку или внести новый ресурс в пере-чень полезных русскоязычных ресурсов,нужно форкнуть указанный выше репо-зиторий, внести изменения и отправитьзапрос на слияние (pull request). Более по-дробная информация есть в README.md.
Есть ли какие-то другие проекты, о кото-рых хотел бы рассказать?
Есть проект реализации протокола TLSна чистом Perl Protocol::TLS, который наданный момент уже поддерживает версиюTLS 1.2. Смысл проекта состоит в том,чтобы уйти от зависимости на OpenSSL,который развивается очень уж неспешно и
консервативно. Попробуйте обновить libsslв каком-нибудь CentOS до свежих версий споддержкой всех новых фич безопасности,шифров и последних версий протоколаTLS. Это практически нереальный квест,так как практически всё современноепрограммное обеспечение линкуется сlibssl.
К сожалению, нехватка свободного време-ни сейчас сказывается на дальнейшем раз-витии проекта.
Где сейчас работаешь? Сколько временипроводишь за написанием Perl-кода?
Я работаю в крупной энергетическойкомпании. Занимаюсь телекоммуникаци-ями, поддержкой средств мониторинга ипромышленных систем учёта.
Программирование не входит в кругмоих рабочих обязанностей, но это един-ственный способ облегчить свою жизнь.Регулярно приходится писать клей междуразличными системами, вносить улуч-шения в систему мониторинга, создаватьи развивать разноплановые внутренниевеб-сервисы.
Вне работы программирую на Perl в основ-ном для своих открытых проектов на github.Но это происходит импульсивно, т.е. возни-кает вдохновение, пишешь код недели напролёт, а потом выгораешь и ждёшь оче-редного озарения.
Стоит ли советовать молодым програм-мистам учить сейчас Perl?
В первую очередь я бы посоветовал мо-лодым ребятам обратить внимание на
свободное программное обеспечение. По-старайтесь выбрать такие программы иокружение, которые являются свободны-ми. Это может быть Linux или одна изсвободных BSD-систем. Выбирайте лю-бой свободный язык: Perl, PHP, Python,JavaScript и прочие. Свободный редакторVim/Emacs/Eclipse. Свободный браузер:Firefox, Chromium и другие. СвободнуюСУБД: PostgreSQL/MySQL и подобные. Нобез фанатизма (привет, Nvidia).
Это простое правило позволит вам не разо-чароваться в жизни и не попасть в кабалук проприетарному вендору, от прихотей ко-торого будет зависеть ваше профессиональ-ное будущее.
Perl стоит выучить, даже если вы не про-граммист. Он позволит вам запросторешать различные задачи.
Вопросы от читателей
Надолго ли хватит сил на perlnews.ru?
Надеюсь, что сил хватит. На самом деле,писать короткие новости и переводы изблогов на порядок проще, чем приду-мывать темы и писать большие статьи.Выделив в дневном расписании какое-тонебольшое время на выпуск новостейможно успешно поддерживать ресурсжизнеспособным.
Но было бы ещё интереснее, если бы появи-лись другие авторы, тогда каждая новостьмогла бы прорабатываться более тщатель-но, что повысило бы качество материаладля посетителей.
Что значит crux?
В студенчестве я играл в одной блэк-метал-банде местной андерграунд-сцены, мы да-же записали один альбом, который назва-ли «crux anasta» (да, с опечаткой, правиль-но пишется «crux ansata»), это один из глав-ных символов древних египтян. Позже, ко-гда мне нужно было придумать свой пер-вый рабочий логин для linux, я взял этотприкольный короткий крукс.
■ Вячеслав Тихановский