pragmatic 34 perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. ·...

50
Pragmatic Perl pragmaticperl.com 12/2015 34

Upload: others

Post on 21-Jan-2021

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

PragmaticPerl

pragmaticperl.com12/2015

34

Page 2: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Pragmatic Perl 34

pragmaticperl.com

Выпуск 34. Декабрь 2015

Page 3: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Другие выпуски и форматы журнала всегда можно загрузить с pragmaticperl.com. С вопро-сами и предложениями пишите на почту [email protected].

Комментарии к каждой статье есть в html-версии. Подписаться на новые выпуски можно поссылке pragmaticperl.com/subscribe.

Авторы статей: Владимир Леттиев, Андрей Шитов, Денис Федосеев

Обложка: Марко Иванык

Корректор: Андрей Шитов

Выпускающий редактор: Вячеслав Тихановский

Ревизия: 2015-12-31 10:36

© «Pragmatic Perl»

Page 4: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Оглавление

1 От редактора . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 Впечатления от воркшопа Saint Perl 2015 . . . . . . . . . . . . . . . . 2

3 Взгляд на 2015 г. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

4 Управление модулями и прекомпиляция в Perl 6 . . . . . . . . . . 7

5 Perl 6-винегрет . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

6 Использование Rust из Perl . . . . . . . . . . . . . . . . . . . . . . . . . 19

7 Обзор CPAN за ноябрь 2015 г. . . . . . . . . . . . . . . . . . . . . . . . 36

8 Интервью с Дмитрием Шаматриным . . . . . . . . . . . . . . . . . . 42

i

Page 5: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

От редактора

1. От редактора

Всех читателей поздравляем с наступающими праздниками и желаем инте-ресных проектов в новом году!

Друзья, журнал ищет новых авторов. Не упускайте такой возможности! Еслиу вас есть идеи или желание помочь, пожалуйста, свяжитесь с нами.

Приятного чтения.

■ Вячеслав Тихановский

1

Page 6: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Впечатления от воркшопа Saint Perl 2015

2. Впечатления от воркшопа Saint Perl 2015

Не изменяя традиции 19 декабря 2015 г. прошёл седьмой ежегодный воркшопSaint Perl для всех любителей и профессионалов мира Perl в Санкт-Петербурге.

Для меня незабываемые впечатления о конференции начались ещё с момен-та прибытия в Санкт-Петербург: затянутое серыми облаками небо, морося-щий дождь и +6ºC. Необычно для середины декабря, да и последующие дниставили температурные рекорды.

В этом году конференция проходила на площадке, предоставленной гене-ральным партнёром конференции — компанией DataArt. На сайте конферен-ции зарегистрировались 53 человека, причём трое из них сделали это ужев день конференции. Не все сразу смогли найти вход в здание, поэтому за10 минут до начала зал был ещё почти пустой, но вскоре он заполнился, по-дошли, возможно, не все, но близко к заявленному числу. Была даже видео-съёмка, но получилась ли она и где будут записи, пока неизвестно.

Открыл конференцию Сергей Романов, поприветствовав слушателей и рас-сказав о плане конференции и намечающихся мероприятиях.

Первый доклад назывался «Протокол HTTP/2. Зачем и как использовать вPerl», и это был мой доклад. Мне трудно сказать, как восприняли докладслушатели, но 40 минут для меня пролетели незаметно. Большая часть до-клада была посвящена протоколу HTTP: истории протокола, недостаткамHTTP/1.1 и достоинствам HTTP/2. Затем проводился обзор реализаций дляPerl: подробно рассмотрен Net::Curl и его работа с HTTP/2, а также Protocol::HTTP2 — как возможная основа для реализаций клиентов и серверов с под-держкой HTTP/2.

После доклада был вопрос о судьбеWebSocket, и для многих стало откровени-ем, что WebSocket не работает поверх HTTP/2 и никакой альтернативы дляего замены HTTP/2 не предлагает. Разработка спецификации WebSocket по-верх HTTP/2 заглохла и похоже никому не нужна.

Следующим докладчиком должен был стать Илья Чесноков, которыйготовил интерактивный доклад, но из-за технической накладки докладпришлось перенести. Поэтому следующим выступал Михаил Матвеев сдокладом «Инструменты для работы с изображениями в Perl».

2

Page 7: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Впечатления от воркшопа Saint Perl 2015

В докладе был сделан обзор самых популярных модулей Perl для работы сизображениями: ImageMagick, GraphicMagick и другие. Как обычно, вопросвыбора модуля возник в результате работы над практической задачей: на-писание своей собственной капчи. Особо в докладе был выделен модульImager, который в отличие от других библиотек не требует установленныхC-библиотек с заголовками (что иногда доставляет проблемы при сборкена некоторых дистрибутивах), так же написан с использованием C/XS, нособирается без проблем, работает быстрее, хоть и не поддерживает большогоспектра форматов. Были представлены бенчмарки, в которых также можнобыло сравнить различия в скорости работы модулей.

Далее был обеденный перерыв, а затем Илья, для которого нашли переход-ник для видео-разъёма, смог подключить свой ноутбук и показать доклад«Технологии асинхронного программирования». Презентация была сделанас помощью Vroom — инструмента, позволяющего показывать слайды в ре-дакторе vim. Доклад шёл целый час и фактически объединил в себе несколь-ко больших докладов по различным техникам асинхронного программиро-вания: это форки, треды и сопрограммы. Было рассказано, чем ужасны Perlтреды и почему Coro — это единственные нормальная реализация тредов (хо-тя это и не совсем треды в привычном понимании). Бенчмарки иллюстриро-вали различия в работе различных реализаций асинхронных техник, как понагрузке процессора, так и по использованию памяти.

Следующим докладчиком был Денис Федосеев, который представил доклад«Легаси это не страшно». Денис поделился опытом борьбы с огромнымлегаси-проектом, где нет ни тестов, ни разделения на пакеты, ни дажеэлементарного use strict (на этом месте особо чувствительные перловикидолжны упасть в обморок). Рассказал о техниках изоляции кода, способах ве-дения исправлений. Презентация была очень красочной, позволяя целикомпроникнуться атмосферой безысходности: живые мертвецы, велосипеды сквадратными колёсами. Но в итоге был сделан вывод, что выживать с легасиможно, и это не страшно.

После кофе-брейка выступил лидер Moscow.pm Павел Щербинин с докладом«Index Condition Pushdown», который был посвящён одноимённой фиче, ко-торая появилась в MySQL 5.6. Слайдов как таковых было не много, в основ-ном все объяснения зарисовывались на флипчарте, при этом очень активнопроисходило взаимодействие со слушателями, собственно это и было ближек духу воркшопа (семинара), когда можно не только слушать, но и пытатьсяпонять, о чём речь и пытаться отвечать на вопросы ;-)

3

Page 8: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Впечатления от воркшопа Saint Perl 2015

Доклад закономерно породил вопрос: зачем MySQL, если есть PostgreSQL, нофлейм был беспощадно отсечён — каждый использует то, что его устраиваети в чём он лучше разбирается.

В завершении конференции были блиц-доклады. Надо сказать, что большин-ство докладов были зарегистрированы уже по ходу конференции.

• Artur Penttinen сделал сразу два блиц-доклада о том как можно рас-парсить конфигурационный файл однострочником и частный случайс конфигурационным файлов в формате ini.

• Илья Чесноков, «О регулярности». Немного философский доклад о со-бытиях в нашей жизни и формировании полезных привычек, напри-мер, регулярное проведение конференций или ежегодное ведение цик-ла рождественских статей Perl Advent Calendar.

• Илья Чернов, «PSPlot — графики в EPS». Доклад был посвящён собствен-ной разработке: модулю psplot, которыйпозволяет рисовать двумерныеграфики в формате EPS.

• ДокладыМихаилаИванова «SWAT»иАлексеяМележика «SparrowHub»были логически объединены и посвящены системе Swat — DSL-языкуи утилитам для быстрой разработки автоматических тестов webприложений и его спутнику sparrowhub, служащего для хранениясценариев тестирования для наиболее популярных веб-приложений(типа wordpress).

• Сергей Романов в докладе «Christmas is coming» наконец упомянул то,что практически не звучало на конференции: Perl 6. На рождество насвсех ждёт стабильный релиз Perl 6, которого так ждали последние 15лет.

После окончания докладов последовала традиционная after party в одном избаров северной столицы (а для некоторых и не в одном). Но это уже другаяистория, впечатления о которой трудно выразить словами, но можно изме-рить в единицах объёма ;-)

■ Владимир Леттиев

4

Page 9: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Взгляд на 2015 г.

3. Взгляд на 2015 г.

Краткий обзор заметных событий в мире Perl за прошедший год

1 февраля

На конференции FOSDEM в Брюсселе Ларри Уолл объявил, что официальнаябета-версия Perl 6 появится 27 сентября (на его 61-летие), а релиз 6.0 ожидает-ся на Рождество 2015-го.

Статья в журнале с заметками с этого выступления: Perl 6, или Get ready toparty.

2 февраля

ВладимирЛеттиев открыл сайт perlnews.ru—новостной блог о всех заметныхсобытиях мира Perl на русском языке.

16 февраля

Разработчики Rakudo объявили, что прекращают поддержку виртуальноймашины Parrot, чтобы не тратить силы на поддержание бекенда, которыйвсе равно не сможет обеспечить некоторые нужные возможности, которыепотребуются в предстоящем релизе Perl 6.0 в 2015 году.

6 апреля

The Perl Foundation объявили о создании фонда поддержки развития ядраPerl 6 (Perl 6 Core Development Fund).

28 апреля

Microsoft выпустил текстовый редактор для программистов Visual StudioCode. Среди языков, для которых доступна подстветка синтаксиса, — Perl иPerl 6.

1 июня

Вышел релиз Perl 5.22. Статьи в журнале:

5

Page 10: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Взгляд на 2015 г.

• Что нового в Perl 5.22• Перевод документа perl5220delta.pod на русский язык

6 июня

Марк Леман анонсировал свой форк Perl 5.22, провокационно назвав егоstableperl.

16 августа

20 лет CPANу.

27 сентября

Perl 6 (в лице Rakudo Star 2015.09) официально получил статус бета-версии.

18 декабря

Языку программирования Perl исполнилось 28 лет.

25 декабря

Релиз Perl 6.

■ Андрей Шитов

6

Page 11: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Управление модулями и прекомпиляция в Perl 6

4. Управление модулями и прекомпиляция в Perl6

25 декабря 2015 г. вышел первый стабильный релиз Rakudo Perl 6, среди новшествкоторого совершенно новая система управления модулями и прекомпиляция.Рассмотрим в деталях процесс загрузки, разрешения зависимостей и компиля-ции модулей.

Обычная загрузка модуля

Традиционный процесс загрузки модуля в Perl 5 выглядит достаточно про-сто: имя модуля преобразуется к имени файла, например, Foo::Bar ожидает-ся быть найденным в файле Foo/Bar.pm. В массиве @INC содержится списоккаталогов, в которых следует производить поиск файлов модулей. Часть ката-логов является фиксированными и получили свои обозначения, например:

• site — каталог для поиска модулей, установленных администраторомсистемы,

• vendor — каталог для модулей, поставляемых с дистрибутивом,• perl — каталог модулей, идущих в поставке Perl

Модули ищутся и загружаются во время компиляции программы из исход-ного кода на диске. Такой же метод до недавнего времени использовался ив Perl 6, но рождественский релиз внёс существенные изменения в такое по-ложение вещей.

Репозитории

Теперь в Perl 6 мы работаем с репозиториями — определённым образом ор-ганизованное хранилище модулей. Репозитории могут быть различных ти-пов, и это первое отличие от традиционных каталогов. Простейший вариантрепозитория совместим с традиционным подходом и хранит файлы моду-лей в соответствии с именем пакета. Более сложный вариант поддерживает

7

Page 12: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Управление модулями и прекомпиляция в Perl 6

установку дистрибутивов модулей вместе с метаинформацией и ресурсами,а также производит прекомпиляцию модулей в байткод.

Ранее используемый массив @*INC ушёл в небытие и теперь при загрузкемодулей используется переменная процесса PROCESS::<$REPO>, которая яв-ляется связанным списком с информацией о доступных репозиториях.1 $ perl6 −e 'for $*REPO.repo−chain −> $n { say $n }'23 inst#/home/user/.perl6/2015.124 inst#/usr/share/perl6/site5 inst#/usr/share/perl6/vendor6 inst#/usr/share/perl67 ...

Как видно, в отличие от Perl 5, в цепочке репозиториев присутствует новыйкаталог, находящийся в каталоге пользователя, запустившего программу, ион имеет максимальный приоритет. Кроме того, присутствует префикс inst#, который указывает на тип репозитория, в данном случае тип CompUnit::Repository::Installation, который поддерживает инсталляцию.

По-прежнему мы можем дополнять список с помощью флага −I или пере-менной окружения PERL6LIB, например:1 $ perl6 −I /opt/perl6 'for $*REPO.repo−chain −> $n { say $n }'23 file#/opt/perl64 inst#/home/user/.perl6/2015.125 inst#/usr/share/perl6/site6 inst#/usr/share/perl6/vendor7 ...

Как видно, если не указать тип репозитория перед путём, то он будет счи-таться традиционным файловым file#.

Что касается выражения use lib '/path/to/lib', то теперь её нельзя ис-пользовать в модулях, только в скриптах.

8

Page 13: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Управление модулями и прекомпиляция в Perl 6

Инсталляция в репозиторий

Инсталляция в традиционныйфайловый репозиторий— это простое копиро-вание файлов. С новым типом репозитория всё несколько сложнее. Рассмот-рим как организован такой репозиторий:1 \2 +− dist3 |4 +− sources5 |6 +− resources7 |8 +− short9 |

10 +− precomp11 \12 + compiler.id13 \14 + ..

При инсталляции дистрибутива Foo, содержащего модуль Foo::Bar, в ката-логе dist создаётся файл с именем, представляющим собой SHA1 от уникаль-ного идентификатора дистрибутива, содержащий метаинформацию о дис-трибутиве в формате JSON. В каталог sources помещаются исходные кодымодуля, в каталог resource - связанные ресурсные файлы, все имена файловгенерируются как уникальные 40-символьные идентификаторы.

В каталог short помещаются файлы с именами как результат хеш-функцииSHA1 от имени соответствующего модуля. В таком файле помещается 40-символьныйидентификатор дистрибутива, в состав которого входит данныймодуль.

В каталог precomp помещается результат компиляции исходного кода в байт-код. Внутри каталога precomp создаётся каталог для текущей версии ком-пилятора (в имя включается даже время сборки компилятора). Дальнейшаяорганизация вложенных каталогов precomp напоминает git: внутри создаёт-ся до 256 двухбуквенных каталогов, в который помещаются скомпилирован-ный байткод, например:1 +− 5C2 \3 + 5C74B123E79B373BB96EC583A5C7EE4F458931BD4 + 5C74B123E79B373BB96EC583A5C7EE4F458931BD.deps

9

Page 14: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Управление модулями и прекомпиляция в Perl 6

5 + 5C74B123E79B373BB96EC583A5C7EE4F458931BD.rev−deps6 +− 7E7 \8 + 7E4AC40F59629C48CCBD390FEB4B2720045910249 + 7E4AC40F59629C48CCBD390FEB4B272004591024.deps

10 + 7E4AC40F59629C48CCBD390FEB4B272004591024.rev−deps

Создаются также файлы .deps и .rev-deps куда помещается данные о зависи-мостях и обратных зависимостях (sha1-хеш имени модуля).

Таким образом, когда в коде встречается запись use Foo::Bar, компиляторвыполняет такую цепочку действий:

1. вычисляет sha1-сумму имени Foo::Bar;2. ищет файл с получившимся id в каталоге short;3. если находит, то по содержимому узнаёт id дистрибутива;4. загружает метаинформацию дистрибутива из каталога dist;5. из метаинформации узнаёт расположение исходного кода нужного мо-

дуля дистрибутива;6. проверяет наличие исходного кода в каталога sources (но не загружает);7. проверяет наличие прекомпилированного кода в precomp;8. если нет прекомпилированного кода, то выполняет загрузку исходного

кода и прекомпиляцию с сохранением байткода;9. загружает из каталога precomp файл с прекомпилированным кодом мо-

дуля;10. проверяет наличие в каталоге precomp файла с таким же именем, но с

окончанием .deps;11. если есть deps-файл, то находит в нём имена source-файлов зависимо-

стей;12. в цикле проходит шаги 2–12 для всех зависимостей.

За инсталляцию отвечает класс CompUnit::Repository::Installation. При-мер кода, выполняющего установку, можно увидеть в скрипте установки дис-трибутива CORE при сборке Rakudo. В целом примерно так:1 my %provides =2 "Foo::Bar" => "lib/Foo/Bar.pm6",3 ;45 # задаём путь к репозиторию для данного процесса

10

Page 15: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Управление модулями и прекомпиляция в Perl 6

6 PROCESS::<$REPO> := CompUnit::RepositoryRegistry7 .repository−for−spec("inst#/path/to/repo");89 # устанавливаем/прекомпилируем

10 $*REPO.install(11 Distribution.new(12 name => "Foo",13 auth => "vendor",14 ver => "0.1",15 provides => %provides,16 ),17 %provides,18 :force,19 );

Недостатки

К сожалению, скорость, с которой появились новые репозитории (хоте-ли успеть к Рождеству), помешала достаточно хорошо протестировать инормально реализовать функционал.

$(DESTDIR)

Большинство дистрибутивов Linux и UNIX-систем используют переменнуюокружения $(DESTDIR), чтобы указать временный каталог для инсталляциипри сборке (например, при сборке пакетов). Новый механизм репозитори-ев затрудняет указание временного префикса, поэтому вышедший Rakudo2015.12 просто падает с ошибкой при установке с использованием $(DESTDIR).

К счастью, это быстро заметили и ввели новую переменную окруженияRAKUDO_PREFIX, которая позволяет переопределить префикс при операцияхс репозиториями. Но это уже войдёт только в следующий релиз.

11

Page 16: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Управление модулями и прекомпиляция в Perl 6

Прекомпиляция

Использование результатов прекомпиляции и сама прекомпиляция выпол-няется только в самом первом репозитории из списка. По умолчанию эторепозиторий из домашнего каталога пользователя. Даже если исходный коднаходится, например, в репозитории vendor и там же есть прекомпилирован-ный код, то rakudo не будет использовать результат прекомпиляции, а занововыполнит прекомпиляцию и создаст необходимые файлы в каталоге пользо-вателя.

В этом отношении каталоги прекомпиляции выглядят вообще отдельнойсущностью от репозиториев.

Процесс прекомпиляция каждого модуля выполняется в отдельном процессе(exec), что безумно затормаживает первый запуск программы, импортирую-щей множество модулей.

Более того, если репозиторий окажется недоступным для записи пользова-телю, то программа просто не запустится с ошибкой.

Rakudo 2016.01

16 января 2016 г. ожидается очередной релиз Rakudo. Вероятно, что-то из об-наруженных проблем будет исправлено.

■ Владимир Леттиев

12

Page 17: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Perl 6-винегрет

5. Perl 6-винегрет

Новогодний оливье — сборная солянка про разные интересные штуки в Perl 6

Юникод

Хранение и обработка символов внутри строк Perl 6 происходит в форматеNFG (Normal FormGrapheme). Это название придумано еще в бытность Parrot,а с практической точки зрения достаточно знать, что из любого символа мож-но получить его NFC-, NFD-, NFKC- и NFKD-формы :-) Это разные канониче-ские и декомпозированные представления символов в юникоде.

Подробности про разные формы представлений с интересными примерамиопубликованы на сайте юникода, а история NFG — в блоге Джонатана.

Посмотреть разные формы помогут одноименные методы, которые можновызывать на односимвольных строках:1 say $s.NFC; # codepoint2 say $s.NFD;3 say $s.NFKC;4 say $s.NFKD;

Полное каноническое название возвращает метод .uniname:1 say 'й'.uniname; # CYRILLIC SMALL LETTER SHORT I

У строк есть полезный метод .encode, позволяющий получить представле-ние в той или иной юникодной кодировке:1 my $name = 'Перл';2 say $name.encode('UTF−8');34 # utf8:0x<d0 9f d0 b5 d1 80 d0 bb>

(Этот метод не поможет перекодировать CP1215 в КОИ-8.)

Для закрепления материала предлагаю посмотреть на вывод упомянутых ме-тодов на разных хитрых символах:

13

Page 18: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Perl 6-винегрет

1 unidump('�');2 unidump('ы');3 unidump('å');4 unidump('é');5 unidump('�'); # один из немногих символов,6 # для которого различаются7 # все канонические представления8 unidump('й');9 unidump('²');

10 unidump('Æ');1112 sub unidump($s) {13 say $s;1415 say $s.chars; # число графем16 say $s.NFC; # code point17 say $s.NFD;18 say $s.NFKC;19 say $s.NFKD;20 say $s.uniname; # юникодное название буквы2122 say $s.NFD.list; # списком2324 say $s.encode('UTF−8').elems; # сколько байтов25 say $s.encode('UTF−16').elems;2627 say $s.encode('UTF−8'); # в виде utf8:0x<...>2829 say '';30 }

Формы NFKC и NFKD, в частности, могут преобразовать надстрочные и под-строчные индексы в обычные цифры:1 say '2'.NFKD; # NFKD:0x<0032>2 say '²'.NFKD; # NFKD:0x<0032>

С помощью функции unimatch можно узнать, принадлежит ли символ к тойили иной группе символов в юникоде. Например:1 say unimatch('ф', 'Cyrillic'); # True

Но нужно быть осторожным, чтобы не разжигать:1 say unimatch('ї', 'Cyrillic'); # True2 say unimatch('ï', 'Cyrillic'); # False

14

Page 19: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Perl 6-винегрет

Здесь были одинаково выглядящие, но разные символы. Их NFD соответ-ственно 0x<0456 0308> и 0x<0069 0308>, а имена — CYRILLIC SMALL LETTERYI и LATIN SMALL LETTER I WITH DIAERESIS.

Юникодные свойства можно проверить и регулярными выражениями:1 say 1 if 'э' ~~ /<:Cyrillic>/;2 say 1 if 'э' ~~ /<:Ll>/; # Letter lowercase

Для создания юникодных строк можно напрямую воспользоваться конструк-тором класса Uni:1 say Uni.new(0x0439).Str; # й2 say Uni.new(0xcf, 0x94).Str; # Ï

Whatever (*)

Whatever — это класс, который позволяет создавать объекты, тип и значениекоторых определяются из контекста. Чтобы создать такой объект, достаточнопоставить звездочку (если она, разумеется, не означает умножение).1 say *.WHAT; # (Whatever)

Whatever удобно использовать для создания простых функций, например:1 my $f = * ** 2; # возведение в квадрат2 say $f(16); # 25634 my $xy = * ** *; # возведение в произвольную степень5 say $xy(3, 4); # 81

Того же результата удастся достичь более традиционным (для старого Perl 6)синтаксисом:1 # Анонимный блок кода с одним аргументом $x2 my $g = −> $x {$x ** 2};3 say $g(16);45 # Блок с двумя аргументами, имена сортируются по алфавиту6 my $h = {$^a ** $^b};7 say $h(3, 4);

15

Page 20: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Perl 6-винегрет

Вполне оправдано использование звездочки для создания интервалов(Range):

Пример с циклом:1 for (5..*) {2 .say; # построчно печатает от 5 до 103 last if $_ == 10;4 }

Пример с массивом:1 my @a = <2 4 6 8 10 12>;2 say @a[3..*]; # (8 10 12)

Отдельно следует рассмотреть, что происходит с отрицательными значени-ями.

Все, начиная с четвертого элемента и заканчивая предпоследним:1 say @a[3..*−2]; # (8 10)

Чтобы получить последний элемент, нельзя просто написать @a[−1]:1 Unsupported use of a negative −1 subscript to index from the end;2 in Perl 6 please use a function such as *−1

Следует добавить звездочку:1 say @a[*−1]; # 12

Звездочка подходит и для создания ленивых списков (то есть таких списков,очередной элемент которых вычисляется по мере необходимости):1 my @a = (1 ... *);2 for (0..5) {3 say @a[$_];4 }

В ленивых списках допустимо подсказать компилятору, как генерировать по-следовательность:1 my @a = (1, 2 ... *); # с шагом 12 my @a = (2, 4 ... *); # четные числа3 my @a = (2, 4, 8 ... *); # степени двойки

16

Page 21: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Perl 6-винегрет

Либо использовать явно определенный блок со способом вычисления:1 my @fib = 0, 1, * + * ... *; # Фибоначчи

Файлы

Имя файла, который сейчас исполняеся, теперь находится в переменной $*PROGRAM−NAME, а не $*PROGRAM_NAME, как было еще совсем недавно.

А вот программа, которая использует встроенную функцию slurp, читаю-щую содержимое текущего файла:1 say slurp $*PROGRAM−NAME;

Противоположная функция — spurt («бить струей»), она записывает данныев файл. Вот пример реализации юниксовой функции cp на Perl 6:1 my ($source, $dest) = @*ARGS;23 my $data = slurp $source;4 spurt $dest, $data;

По умолчанию файл либо создается, либо перезаписывается. Ключ (имено-ванный аргумент) :append попросит добавлять новые данные в конец фай-ла:1 spurt $dest, $data, :append;

Чтобы упасть с ошибкой при попытке записи в существующий файл, добавь-те опцию :createonly (:append при этом станет неактуальной):1 spurt $dest, $data, :createonly;

И slurp, и spurt принимают аргумент с именем кодировки enc, но опять же,старых кодировок типа 'KOI8' там нет (да и не надо):1 my $data = slurp $source, enc => 'UTF−8';2 spurt $dest, $data, enc => 'UTF−16';

Если на строке вызвать метод .IO, то возвращается объект класса IO::Path.Метод определен так:1 method IO() returns IO::Path:D

17

Page 22: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Perl 6-винегрет

(:D здесь не ржачный смайл, а означает defined.)

Например, как получить абсолютный путь к локальному файлу:1 say 'file1.pl'.IO.abspath;

Как получить содержимое такого-то каталога:1 say '.'.IO.dir;

Проверки существования файлов и каталогов теперь выглядят так:1 say 1 if 'file.txt'.IO.e; # −e 'file.txt' в Perl 52 say 1 if 'file.txt'.IO.f; # −f3 say 1 if '..'.IO.d; # −d

Остальные методы, перечисленные в документации, вполне понятны безобъяснений. Например, для выделения из имени файла расширения можновоспользоваться методом .extension:1 say $filename.IO.extension;

■ Андрей Шитов

18

Page 23: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

6. Использование Rust из Perl

Встраивание Rust в Perl с помощью FFI

Rust — язык системного программирования, развиваемый Mozilla Fundation.Призван заменить собой С. Обеспечивает безопасную работу с памятью ипрочие приятные мелочи, которых иногда так не хватает в С, при этом недает оверхеда по производительности (в теории).

Подробности языковых конструкций я тут расписывать сильно не буду, в це-лом, все примеры укладываются в первые 4 главы книги по Rust.

Сначала установим Rust последней версии (1.5 на момент написания). Ин-струкции по установке на все поддерживаемые платформы можно найти насайте — https://www.rust-lang.org/downloads.html.

Будем считать, что Rust уже установлен и даже работает. Попробуем его ис-пользовать из Perl.

Сначала опробуем пример из документации, создадим новый проект с по-мощью Cargo:1 cargo new embed2 cd embed

Добавим в Cargo.toml следующее содержимое:1 [lib]2 name = "embed"3 crate−type = ["dylib"]

Этим мы говорим карго, что мы хотим получить библиотеку, а не бинарники библиотека должна линковаться с кодом на C.

Теперь отредактируем src/lib.rs и приведем его к такому виду:1 use std::thread;23 #[no_mangle]4 pub extern fn process() {5 let handles: Vec<_> = (0..10).map(|_| {6 thread::spawn(|| {7 let mut x = 0;

19

Page 24: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

8 for _ in (0..5_000_000) {9 x += 1

10 }11 x12 })13 }).collect();1415 for h in handles {16 println!("Thread finished with count={}",17 h.join().map_err(|_| "Could not join a thread!").unwrap()

);18 }1920 println!("done!");21 }

Это приложение запускает 10 тредов, каждый из которых считает до 5 000000, собирает от них возвращаемое значение (счетчик x) и выводит это нам.

Соберем его:1 cargo build −−release

В каталоге target/release у нас появится файл libembed.so (для Mac OS рас-ширение будет dylib, дляWin — dll, я все это проделываю на маке, так что биб-лиотеки везде будут с расширением dylib, вам же надо будет поправить подсвою систему) — это наша подключаемая библиотека. При формированиибиблиотеки Cargo автоматически добавляет префикс lib к имени проекта,указанного в name.

Настало время вызвать ее из Perl. Так как XS-биндингов в Perl для Rust ещене существует (ну или я их не нашел), то мы будем использовать FFI::Raw.Этот модуль позволяет из кода на Perl дергать функции в библиотеках на С.Модуль весьма низкоуровневый, но для начала это даже хорошо.

Создадим файл main.pl со следующим содержимым:1 #!/usr/bin/env perl23 use v5.16;4 use FFI::Raw;56 my $process = FFI::Raw−>new(7 'target/release/libembed.dylib', 'process',8 FFI::Raw::void,

20

Page 25: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

9 );1011 say $process−>call();1213 say "Done!";

Здесь в конструкторе мы указываем путь к нашей библиотеке, имя функции,которую мы хотим использовать, и тип возвращаемого значения. В данномслучае функция у нас ничего не возвращает, так что это будет void.

И запустим наш перловый скрипт:1 alpha6$ perl ./main.pl2 Thread finished with count=50000003 Thread finished with count=50000004 Thread finished with count=50000005 Thread finished with count=50000006 Thread finished with count=50000007 Thread finished with count=50000008 Thread finished with count=50000009 Thread finished with count=5000000

10 Thread finished with count=500000011 Thread finished with count=500000012 done!13 Done!

Этот код может валиться с Segmentation fault 11 перед выходом из скрип-та. Это связано с выводом с STDOUTиз кода на Rust. Видимо, FFI как-то кривообрабатывает закрытие дескрипторов. На маке валится стабильно, на Linuxработает без ошибок, на Windows не проверял. Видимо, влияют какие-то осо-бенности платформы.

Вызывать числодробилки из Perl это конечно хорошо, но как насчет переда-чи параметров функции? Тоже можно, посчитаем факториал.

Приведем src/lib.rs к виду:1 #[no_mangle]2 pub extern fn fact(x: i32) −> i32 {3 let mut fact = 1;4 for i in 1..x+1 {5 fact *= i;6 }78 return fact;

21

Page 26: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

9 }

Здесь мы объявляем публичную функцию fact, которая принимает на входчисло в виде 32-битного целого и то же самое возвращает в качестве резуль-тата.

Также обратите внимание: #[no_mangle]надо указывать перед каждойфунк-цией, которую мы хотим экспортировать. Если убрать эту строку и попробо-вать вызвать рассчет факториала, мы получим ошибку, несмотря на то, чтофункция объявлена публичной:1 alpha6$ perl ./main.pl2 dlsym(0x7ffeda40abd0, fact): symbol not found at ./main.pl line

13.

no_mangle говорит компилятору, чтобы он не изменял имя функции во вре-мя компиляции, что делает возможным доступ к ней из других языков.

Приведем main.pl к виду:1 my $fact_fn = FFI::Raw−>new(2 'target/release/libembed.dylib', 'fact',3 FFI::Raw::int,4 FFI::Raw::int,5 );67 my $fact_val = $fact_fn−>call(30);89 say "Factorial [$fact_val]";

Сохраняем, запускаем:1 alpha6$ perl ./main.pl2 Factorial [1409286144]3 Perl code done!

Хм, кажется, что-то пошло не так…

В этом примере можно увидеть наглядно различия Perl и языков более низ-кого уровня. Если посмотреть на результат работы функции, то видно чтофакториал 30 немножко не является факториалом 30, хотя бы потому что внем должно быть 22 цифры. При этом просто увеличение разрядности до u64не поможет, потому что туда он тоже не влезает. В общем, мораль сей басни

22

Page 27: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

такова — следите за переполнением переменных, так как компилятор этогоне отслеживает, и рантайм-проверок по умолчанию тоже нет.

Впрочем, при изменении разрядности с int до int64, факториал 14 рассчиты-вается верно, если верить калькулятору, а все, что выше 15 — это уже матема-тика с хитрыми алгоритмами, Rust из коробки с ней работать не умеет.

Еще одна проблема — FFI::Raw не позволяет напрямую передавать и возвра-щать из внешнего кода что-то сложнее примитивных типов. То есть передатьв функцию хеш или вернуть вектор не получится. Но всегда можно работатьсо структурами С, а перегнать Perl-структуру в сишную — задача элементар-ная.

Приведем наш lib.rs к виду:1 pub struct Args {2 init: u32,3 by: u32,4 }56 #[no_mangle]7 pub extern fn use_struct(args: &Args) −> u32 {8 println!("Args: {} − {}", args.init, args.by);9

10 return args.init;11 }

Здесь мы объявляем структуру Args и делаем ее доступной снаружи нашейбиблиотеки указанием pub. В функции use_struct мы говорим компилято-ру, что ожидаем на входе указатель на эту структуру. Ну и возвращаем об-ратно первый элемент структуры.

В перловый код вставим такое:1 my $packed = pack('LL', 42, 21);2 my $arg = FFI::Raw::MemPtr−>new_from_buf($packed, length $packed)

;34 my $foo = FFI::Raw−>new(5 $shared, 'test_struct',6 FFI::Raw::uint,7 FFI::Raw::ptr,8 );9

10 my $val = $foo−>($arg); #Получаем структуру из Rust кода

23

Page 28: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

11 say "result [$val]";

Здесь мы упаковываем данные для структуры (два числа int32), затем со-здаем из них объект FFI::Raw::MemPtr, который выделяет область памятии укладывает туда упакованную стуктуру. Затем мы привязываемся к функ-ции test_struct из нашей библиотеки и говорим, что будем передавать внее указатель.

Соберем и запустим:1 alpha6$ cargo build −−release2 alpha6$ perl ./main.pl3 Args: 42 − 214 result [42]

Поздравляю, мы только что передали структуру данных в нашу библиотекуна Rust. Попробуем теперь сделать с этой структурой что-то более осмыслен-ное.

Создадим счетчик (действие не особо осмысленное, зато показывает как сэтим всем работать). Приведем наш lib.rs к виду:1 #![allow(non_snake_case)]2 use std::mem::transmute;34 pub struct Args {5 init: u32,6 by: u32,7 }89 pub struct Counter {

10 val: u32,11 by: u32,12 }1314 impl Counter {15 pub fn new(args: &Args) −> Counter {16 Counter{17 val: args.init,18 by: args.by,19 }20 }2122 pub fn get(&self) −> u32 {23 self.val24 }

24

Page 29: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

2526 pub fn incr(&mut self) −> u32 {27 self.val += self.by;28 self.val29 }3031 pub fn decr(&mut self) −> u32 {32 self.val −= self.by;33 self.val34 }35 }3637 #[no_mangle]38 pub extern fn createCounter(args: &Args) −> *mut Counter {39 let _counter = unsafe { transmute(Box::new(Counter::new(args)

)) };40 _counter41 }4243 #[no_mangle]44 pub extern fn getCounterValue(ptr: *mut Counter) −> u32 {45 let mut _counter = unsafe { &mut *ptr };46 let val = _counter.get();47 return val;48 }4950 #[no_mangle]51 pub extern fn incrementCounterBy(ptr: *mut Counter) −> u32 {52 let mut _counter = unsafe { &mut *ptr };53 _counter.incr()54 }5556 #[no_mangle]57 pub extern fn decrementCounterBy(ptr: *mut Counter) −> u32 {58 let mut _counter = unsafe { &mut *ptr };59 _counter.decr()60 }6162 #[no_mangle]63 pub extern fn destroyCounter(ptr: *mut Counter) {64 let _counter: Box<Counter> = unsafe{ transmute(ptr) };65 // Drop66 }

Этот код я честно утащил отсюда, правда он не заработал на новой версиикомпилятора, да и с FFI::Raw у него тоже любовь не сложилась, пришлосьего немного поправить. Но ничего, нам, пользователям Mojolicious, не при-

25

Page 30: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

выкать.

Что здесь происходит? Сначала создаются две структуры данных: Args иCounter. В целом они одинаковые, но для Counter мы создаем реализацию,которая добавляет набор методов к нашей структуре.

Затем мы объявляем публичную функцию createCounter, которая на входпринимает указатель на структуру данных Args. Из этой структурымы созда-ем объект Counter, который упаковываем в контейнер Box::new, который бу-дет доступен через указатель. Работа с transmute дело опасное, поэтому мыоборачиваем создание контейнера в unsafe и этим самым мы говорим ком-пилятору, что мы сами позаботимся о проверке на безопасность всей этойконструкции (чего мы не делаем в данном случае).

После создания контейнера мы возвращаем из функции изменяемый указа-тель, с которым и будем дальше работать везде.

Теперь создадим файл counter.pl, который будет использовать нашу новуюбиблиотеку:1 #!/usr/bin/env perl23 use v5.16;4 use FFI::Raw;56 my $shared = 'target/release/libembed.dylib';78 my $packed = pack('LL', 42, 21);9 my $arg = FFI::Raw::MemPtr−>new_from_buf($packed, length $packed)

;1011 my $createCounter = FFI::Raw−>new(12 $shared, 'createCounter',13 FFI::Raw::ptr, FFI::Raw::ptr14 );1516 my $getCounterValue = FFI::Raw−>new(17 $shared, 'getCounterValue',18 FFI::Raw::uint, FFI::Raw::ptr19 );2021 my $incrementCounterBy = FFI::Raw−>new(22 $shared, 'incrementCounterBy',23 FFI::Raw::uint, FFI::Raw::ptr24 );

26

Page 31: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

2526 my $ptr = $createCounter−>($arg);2728 my $val = $getCounterValue−>($ptr);29 say "Current value [$val]";3031 my $nval = $incrementCounterBy−>($ptr);32 say "New value [$nval]";

Здесь мы сначала привязываемся к функции createCounter и говорим, чтобудем передавать указатель и ждем на выходе указатель. Затем привязыва-емся к функции getCounterValue и говорим, что передаем ей указатель иждем unsigned int. Для всех остальных функций должны быть созданы ана-логичные записи, здесь я их описывать не стал.

Дальшемы вызываем createCounter, которому передаем собранную рукамиструктуру Args и получаем обратно указатель на контейнер со счетчиком.Дальше мы используем этот указатель для изменения значений счетчика.

Соберем это все дело и запустим:1 alpha6$ cargo build −−release2 alpha6$ perl ./main.pl3 Current value [42]4 New value [63]

В выводе видно, что мы получили текущее значение счетчика после созда-ния, а потом изменили его значение.

Теперь мы умеем получать структру из Rust и передавать ее обратно в биб-лиотеку. Однако есть проблема — если мы хотим использовать эту структу-ру внутри Perl кода, то нас ждет небольшое разочарование. У меня так ине получилось привести то, что возвращает Rust, во что-то пригодное дляиспользования в Perl. Если кто-то знает, как это сделать, — напишите в ком-ментариях, а?

Но структуры-то получать хочется! Что ж, пришло время добавить еще одинслой абстракции — используем FFI::Platypus вместо FFI::Raw.

FFI::Platypus является намного более суровым инструментом и предостав-ляет кучу опций, позволяя не заморачиваться с низкоуровневой работой сданными в отличие от FFI::Raw.

27

Page 32: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

Проверим, что у нас все работает как надо. Установим FFI::Platypus и FFI::Platypus::Lang::Rust, этот модуль позволяет использовать при объявлени-ях структур и функций структуры из Rust, а не запоминать маппинг междуRust и C.

Изменим lib.rs и создадим файл plat.pl с содержимым, указанным ниже.

src/lib.rs:1 #[no_mangle]2 pub extern fn hello_plat(arg: u32) {3 println!("Hello PL {}", arg);4 }

plat.pl:1 #!/usr/bin/env perl2 use v5.16;3 use FFI::Platypus;45 my $shared = 'target/release/libembed.dylib';67 my $ffi = FFI::Platypus−>new();89 $ffi−>lib($shared);

10 $ffi−>lang('Rust');11 $ffi−>attach( hello_plat => ['u32'] => 'void' );12 hello_plat(1);

Здесь мы создаем объект FFI::Platypus и указываем ему путь к библиоте-ке — $ffi−>lib($shared), затем указываем, какой язык мы хотим исполь-зовать $ffi−>lang('Rust'). После этого указания FFI сам подгрузит модульFFI::Paltypus::Lang::<LangName>, и можно будет использовать фичи дляконкретного языка (соответствующий модуль должен быть предварительноустановлен).

Далее мы добавляем функцию из библиотеки в перловый код, конструкция$ffi−>attach создает функцию с указанным именем, которая транслируетданные в/из соответстующую библиотечную функцию. Функция создается впространстве имен модуля, так что надо следить, чтобы не было перекрытияфункций из библиотеки и текущего пакета.

Собираем, запускаем:1 alpha6$ cargo build −−release

28

Page 33: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

2 alpha6$ perl ./plat.pl3 Hello PL 1

Все работает как и задумано.

Настало время получить желанную структуру из нашей библиотеки.

В очередной раз переделаем наш src/lib.rs:1 use std::mem::transmute;23 pub struct Args {4 init: u32,5 by: u32,6 descr: String,7 }89 impl Args {

10 pub fn new(init: u32, by: u32, descr: String) −> Args {11 Args{12 init: init,13 by: by,14 descr: descr,15 }16 }17 }1819 #[no_mangle]20 pub extern fn get_struct() −> *mut Args {21 let my_struct = unsafe { transmute(Box::new(Args::new(42, 1,

"hi from Rust!".to_string()))) };22 my_struct23 }

Здесь мы добавляем к нашей старой доброй Args еще одно поле с типомString, в которое мы будет записывать строку.

Затеммы создадимимплементацию для более каноничного создания нашейструктуры (без этого можно обойтись, но неправильно это как-то). Создадимметод new, на вход которого будем передавать два числа и строку. Ну а даль-ше в функции просто создадим указатель на нашу структуру и вернем егоперловому коду.

Обратите внимание, как создается объект String, в Rust есть два типа строк—

29

Page 34: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

str и String. В чем же отличия между str и String? str это так называемыйстроковый срез. Он имеет фиксированную длину и неизменяем, поэтому мыне можем использовать их в структуре (на самом деле можем, но с некоторы-ми затейливыми телодвижениями). Тип String представляет собой строку,размещаемую в куче и гарантированно явлющуюся UTF-8 строкой. ОбычноString получается из str путем преобразования через .to_string.

Обратное преобразование осуществляется через & — str = &String.

Более подробно об этом можно почитать в документации.

Теперь получим данные из Rust:1 use v5.16;2 package My::RustStr;34 use FFI::Platypus::Record;56 # Описываем структуру данных, которую мы ждем из библиотеки7 record_layout(qw(8 uint rs_counter9 uint rs_by

10 string rs_descr11 ));1213 my $shared = 'target/release/libembed.dylib';1415 my $ffi = FFI::Platypus−>new;16 $ffi−>lib($shared);17 $ffi−>lang('Rust');1819 # Связываем структуру с нашим пакетом MyRustStr и присваиваем ей

алиас rstruct20 $ffi−>type("record(My::RustStr)" => 'rstruct');2122 # Аттачим библиотечную функцию get_struct в наш пакет23 # и указываем, что ждем от нее объявленную выше структуру24 $ffi−>attach( get_struct => [] => 'rstruct', sub {25 my($inner, $class) = @_;26 $inner−>();27 });2829 package main;3031 # Используем наш пакет My::RustStr для работы с библиотекой32 my $str = My::RustStr−>get_struct;

30

Page 35: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

3334 printf "Struct is [%d][%d][%s]\n",35 $str−>rs_counter,36 $str−>rs_by,37 $str−>rs_descr;

Сначала мы объявляем пакет My::RustStr, в котором описываем структуруданных, которую мы хотим от нашей библиотеки. Из-за особенностей мо-дуля FFI запись record_layout может быть только одна на пакет (на самомделе нет, но лучше так не делать), поэтому мы выделяем нашу функцию вотдельный пакет.

Затем мы создаем новый тип данных в пакете My::RustStr $ffi−>type("record(My::RustStr)" => 'rstruct'); и называем его rstruct.

Далее мы, как обычно, создаем биндинг до библиотеки и эспортируемее в пространство имен пакета My::RustStr. Обратите внимание на $ffi−>attach( get_struct => [] => 'rstruct', sub {, здесь в качестве воз-вращаемого значения функции мы указываем, что хотим получить нашуструктуру rstruct. Также мы указываем кастомную функцию-обработчик,передавая coderef последним аргументом. В данном случае он не делаетничего кроме вызова библиотечной функции, но туда можно добавитькакую-то дополнительную обработку до/после вызова внешней библитеки.

Затем мы просто распечатываем содержимое нашей структуры.

Теперь мы также можем передать структуру в нашу библиотеку без шаман-ства с pack и указателями. Изменим наш перловый код работы со счетчиком.1 use v5.16;23 package MyCounter;45 use FFI::Platypus::Record;67 record_layout(qw(8 uint rs_counter9 uint rs_by

10 ));1112 package main;1314 my $shared = 'target/release/libembed.dylib';15

31

Page 36: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

16 my $ffi = FFI::Platypus−>new;17 $ffi−>lib($shared);18 $ffi−>lang('Rust');1920 # Создаем новую структуру данных с именем CounterStr21 $ffi−>type('record(MyCounter)' => 'CounterStr');2223 # Аттачим функции из библиотеки24 $ffi−>attach(createCounter => ['CounterStr'] => 'opaque');25 $ffi−>attach(getCounterValue => ['opaque'] => 'u32');26 $ffi−>attach(incrementCounterBy => ['opaque'] => 'u32');2728 # Создаем структуру, из которой мы создадим счетчик29 my $counter = MyCounter−>new(30 rs_counter => 10,31 rs_by => 2,32 );3334 # Создаем объект счетчика и используем его для работы35 my $ptr = createCounter($counter);36 say getCounterValue($ptr);37 say incrementCounterBy($ptr);

Здесь мы используем opaque в качестве возвращаемого значения функцииcreateCounter так как нам нужен сырой указатель для работы с остальнымиподключенными функциями. Но при желании этот указатель можно превра-тить в структуру нужного формата с помощью функции cast.

В Rust-коде ничего менять не надо.

Запускаем:1 alpha6$ perl ./plat.pl2 103 12

Итого, мы создали новый объект счетчика и изменили его.

Теперьмыумеем работать с большей частью случаев, которые наммогут при-годиться при использовании подключаемых библиотек (не только на Rust).Осталось научиться все это автоматически собирать при установке перлово-го модуля.

Для этого нам пригодятся Module::Build и Module::Build::FFI::Rust.

32

Page 37: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

Приведем структуру проекта к виду:1 Build.PL2 ffi3 lib4 plat.pl

В lib у нас лежат Perl-библиотеки нашего проекта, в ffi— Rust-исходники.Build.PL выглядит так:1 #!/usr/bin/env/perl23 use strict;4 use Module::Build;5 use Module::Build::FFI::Rust;67 my $build = Module::Build::FFI::Rust−>new(8 module_name => 'MyCounter::Record',9 dist_abstract => 'FFI test',

10 create_makefile_pl => 'traditional',11 dist_author => 'Denis Fedoseev <denis.fedoseev@gmail.

com>',12 create_readme => '0',13 license => 'perl',14 configure_requires => {15 'Module::Build' => 0.38,16 'File::Which' => 0,17 'Module::Build::FFI' => '0.18'18 },19 build_requires => {},20 requires => {21 'perl' => '5.016000',22 'FFI::Platypus' => 0,23 'FFI::Platypus::Lang::Rust' => 0,2425 },26 recommends => {},27 recursive_test_files => 0,28 sign => 0,29 create_readme => 1,30 create_license => 1,31 );3233 $build−>create_build_script;

Обратите внимание на использование Module::Build::FFI::Rust вместообычного Module::Build. Запускаем установку, подготавливаем Build-

33

Page 38: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

скрипт:1 alpha6$ perl ./Build.PL2 Can't find dist packages without a MANIFEST file3 Run 'Build manifest' to generate one45 WARNING: Possible missing or corrupt 'MANIFEST' file.6 Nothing to enter for 'provides' field in metafile.7 Created MYMETA.yml and MYMETA.json8 Creating new 'Build' script for 'MyCounter−Record' version 'v0

.0.2'

Собираем наши модули:1 alpha6$ ./Build2 cargo build −−release3 Updating registry `https://github.com/rust−lang/crates.io−

index`4 Compiling winapi v0.2.55 Compiling libc v0.2.46 Compiling winapi−build v0.1.17 Compiling advapi32−sys v0.1.28 Compiling rand v0.3.129 Compiling embed v0.1.0 (file:///Users/alpha6/projects/tests/

build/ffi)10 Building MyCounter−Record

Устанавливаем:1 alpha6$ ./Build install2 cargo build −−release3 Building MyCounter−Record4 Files found in blib/arch: installing files in blib/lib into

architecture dependent library tree5 Installing /Users/alpha6/perl5/perlbrew/perls/perl−5.20.3/lib/

site_perl/5.20.3/darwin−2level/auto/MyCounter/Record/Record.bundle

6 Installing /Users/alpha6/perl5/perlbrew/perls/perl−5.20.3/lib/site_perl/5.20.3/darwin−2level/MyCounter/Record.pm

MyCounter/Record/Record.bundle это и есть наша Rust-библиотека, установ-ленная в систему.

Теперь мы умеем работать с Rust-кодом из Perl и, самое главное, собиратьиз этого полноценные пакеты, которые и на CPAN выложить можно :)

В целом все, что описано в этой статье со стороны Perl, применимо к любо-

34

Page 39: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Использование Rust из Perl

му языку, который умеет изображать из себя C-библиотеку. Так что теперьвы всегда сможете взять нужную библиотеку, хоть на Java, и использовать вкорыстных целях.

■ Денис Федосеев

35

Page 40: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Обзор CPAN за ноябрь 2015 г.

7. Обзор CPAN за ноябрь 2015 г.

Рубрика с обзором интересных новинок CPAN за прошедший месяц.

Статистика

• Новых дистрибутивов — 154• Новых выпусков — 778

Новые модули

HTTP::Cookies::PhantomJS

HTTP::Cookies::PhantomJS — расширение для HTTP::Cookies, которое поз-воляет использовать файлы с куками формата, которые применяются в веб-скрапере PhantomJS. Это бывает полезно, когда куки устанавливаются в ре-зультате работы js-кода на стороне клиента при загрузке ресурса в PhantomJS,а последующие ресурсы можно загрузить, используя полученные куки, с по-мощью более легковесного веб-клиента, например, LWP::UserAgent.

GCCJIT

GCCJIT — это обвязка к библиотеке libgccjit, которая позволяет на лету фор-мировать и компилировать код в машинные инструкции.

Locale::TextDomain::OO::Extract::Xslate

Locale::TextDomain::OO::Extract::Xslate позволяет извлекать строки дляперевода из шаблонов Text::Xslate для последующего использования вLocale::TextDomain::OO.

36

Page 41: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Обзор CPAN за ноябрь 2015 г.

DOM::Tiny

DOM::Tiny — это минималистичный HTML/XML DOM-парсер с поддержкойCSS-селекторов.1 my $dom = DOM::Tiny−>new(<<EOF);2 <div>3 <p id="a">Test</p>4 <p id="b">123</p>5 </div>6 EOF78 say $dom−>at('#b')−>text; # 1239

10 $dom−>find('div p')−>last−>append('<p id="c">456</p>');1112 say $dom−>at('#c')−>text; # 456

App::remarkpl

App::remarkpl — это утилита, позволяющая запустить локальный веб-сервер на основе Mojolicious для отображения презентаций на основе remark.В качестве параметра указывается путь к файлу с презентации в форматеMarkdown, после запуска презентация может быть открыта в браузере поадресу localhost:3000

Devel::Trepan::Deparse

Devel::Trepan::Deparse — это плагин для отладчика Devel::Trepan, кото-рый добавляет две новые команды: deparse и deval. Команда deparse позво-ляет показать какой код будет выполняться в следующей инструкции, чтобывает полезно, когда отладчик остановился на строке, в которой несколькоопераций и не ясно какая из них будет выполняться на следующем шаге:1 if ( grep { $_ eq 'foo' } @bar ) {...}

выражение внутри if или уже блок кода grep для какого-то текущего зна-чения @bar? Команда deparse покажет какая именно операция будет выпол-няться следующей:

37

Page 42: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Обзор CPAN за ноябрь 2015 г.

1 : deparse2 # code to be run next...3 $_4 # contained in...5 $_ eq 'foo'

Mail::DKIM::Iterator

Модуль Mail::DKIM::Iterator позволяет организовать проверку DKIM-записей в почтовых сообщениях и добавлять DKIM-подпись к ним. Основноеотличие от Mail::DKIM — это возможность организовать неблокирующуюсяпотоковую обработку писем.

Unix::Pledge

Недавно появившийся в OpenBSD системный вызов pledge(2) теперь можноиспользовать в perl-программах, которые будут работать на этой платфор-ме, с помощью модуля Unix::Pledge. Модуль позволяет наложить ограниче-ния на процесс, например, запретить чтение или запись файлов, с указаниемсписка файлов-исключений.

Perl6::Export

Perl6::Export реализует Perl 6 роль is export для Perl 5 модулей, позволяяизящно экспортировать функции модуля. Например, сравнение с Exporter:1 package My::Module; | package My::Module;2 use Exporter; | use Perl6::Export;3 |4 our @EXPORT = qw(foo bar); | sub foo is export(:MANDATORY);5 | sub bar is export(:MANDATORY);6 |7 our @EXPORT_OK = qw(baz); | sub baz is export(:DEFAULT :qux);8 our %EXPORT_TAGS = |9 qw(qux => [qw(baz)]); |

38

Page 43: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Обзор CPAN за ноябрь 2015 г.

Pg::Reindex

Индексы Postgresql должны периодически пересоздаваться для достиже-ния оптимальной производительности. Например, это можно сделать спомощью команды REINDEX, но в этом случае потребуется эксклюзивнаяблокировка всей таблицы.

Модуль Pg::Reindex выполняет создание индекса с помощью CREATE INDEXCONCURRENTLY, который может выполняться без блокировки. Затем он начи-

нает транзакцию, в которой удаляет старый индекс и переименовывает но-вый. Таким образом достигается пересоздание индекса без длительной бло-кировки.

Обновлённые модули

Sereal 3.010

Вышло обновление (де)сериализатора Sereal. В новых выпусках исправле-но множество багов, включая несколько случаев краха десериализатора, ко-торые были обнаружены при тестирование с помощью фазера AFL.

JSON::Validator 0.63

Модуль JSON::Validator позволяет проводить проверку данных в форматеJSONна соответствие JSON-схеме. В новой версии удалена поддержка исполь-зованиямодулей YAMLи YAML::Tiny для загрузки JSON-схемы вформате yaml(поддерживаются только YAML::XS и YAML::Syck). Связано это с тем, что YAMLи YAML::Tiny в некоторых случаях некорректно выполняют разбор форматаyaml.

PathTools 3.60

Вышло обновление дистрибутива PathTools, включающий модули для ра-боты с путями на различных поддерживаемых в Perl платформах. В новой

39

Page 44: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Обзор CPAN за ноябрь 2015 г.

версии включён модуль File::Spec::AmigaOS для поддержки платформыAmigaOS.

MIME-Types 2.12

В новой версии дистрибутива MIME−Types обновлена база данных MIME-типов, в соответствии с текущим состоянием в IANA. Требования к версииPerl снижены до 5.6.

utf8::all 0.017

Прагма utf8::all тотально включает UTF-8: для исходного кода программы,перекодирует открываемые файлы и аргументы, переданные в команднойстроке, разрешает использование последовательностей \N{...} для заданияюникод-символов по их имени и т.д. В новой версии появилась возможностьотключать эффект прагмы, с помощью no utf8::all.

PDL 2.015

Вышел новый релиз PDL — модуля для работы научных вычислений и отоб-ражения данных. Как указано в журнале изменений — это отполированныйрелиз с исправлением всех замечаний обнаруженных в предыдущей версиис улучшенной поддержкой 64-битных целых.

perl 5.23.5

Вышла новая версия Perl 5.23.5 для разработчиков. В новом релизе проведенаоптимизация, которая ускорила выполнение арифметических операций, та-ких как сложение, вычитание и умножение. Кроме того, теперь быстрее сталиработать операции ++ и −−. Исправлено несколько ошибок с крахом интер-претатора, например, в функции pack: perl −e 'pack "WH200000", \0'

40

Page 45: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Обзор CPAN за ноябрь 2015 г.

App::perlbrew 0.74

Обновился менеджер Perl-инсталляций perlbrew. В новой версии появиласьподдержка переменной окружения PERLBREW_LIB_PREFIX, которая позволя-ет добавить каталог с библиотеками, имеющей приоритет над локальнымикаталогами библиотек perlbrew (т.е. ./lib:$PERL5LIB). Теперь при загрузкефайлов будет отдаваться предпочтение https-ресурсам и обязательно прове-ряться их сертификат.

podlators 4.00

Вышел новый мажорный релиз утилит для конвертирования POD-файлов.Теперь все входящие в дистрибутив модули используют единую версию. Ре-лиз содержит большое количество исправлений, накопившихся с последнегорелиза, вышедшего два года назад.

■ Владимир Леттиев

41

Page 46: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Интервью с Дмитрием Шаматриным

8. Интервью с Дмитрием Шаматриным

Дмитрий Шаматрин — программист, с недавнего времени организатор Perl-конференций

Как и когда научился программировать?

Во всей этой кухне я относительно недавно. Первые попытки были в школе,это был 2005-2006 год, и даже что-то получалось.

Хорошо помню, что Паскаль мне тогда очень не понравился. Но серьезнопригодилось программирование в процессе написания диплома в универе.Если кто не в курсе, по образованию я химик.

Так вот, есть такой большой и страшный аппарат — масс-спектрометр. Онопределяет состав вещества, разбивая молекулу на фрагментарные ионы, ко-личество которых в единицу времени регистрируется масс-анализатором. Поним определяется состав. И вот если молекула большая, ионов будет много,и они будут разные. Их надо опознать и посчитать. Руками это делать дол-го и не интересно, особенно, если таких спектров несколько. Вот пришлосьписать скрипт. Выбрал Perl, так как уже имел минимальный опыт с ним ипримерно понимал, что да как.

Какой редактор используешь?

Emacs. Если/когда нет emacs, могу использовать vim. Тут уже дело привычки.Так сложилось, в основном, исторически. Долгое время под языки, с которы-ми я работаю, не было вменяемых IDE. А потом уже просто привык, и ещераз переучиваться ради сиюминутного профита смысла для себя не вижу.

Как и когда познакомился с Perl?

Тут хочу сказать, что винда мне особо никогда не нравилась, да и сейчас ненравится. В 2006-2013 году моей основной системой был линукс, потом мак.Так вот.

С Perl я познакомился примерно в 2007 году. У нас в городе была локаль-ная сеть, подключение ВПН в которой было не самой тривиальной задачей.Провайдеры тогда особо не заморачивались с поддержкой пользователей на

42

Page 47: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Интервью с Дмитрием Шаматриным

линуксе. Пришлось всю автоматизацию подключения сделать на Perl.

С какими другими языками интересно работать?

Erlang, Haskell, Lua.

Что, по-твоему, является самым большим преимуществом Perl?

Не могу выделить одно преимущество, поэтому вот тот список, благодарякоторому я еще пишу на Perl.

• Нечеловеческая гибкость.• Возможность решать проблемы, как правило, малой кровью.• Быстрая разработка.• Вменяемое событийное программирование.• Ссылочная механика.• Здравая и продуманная система модулей/библиотек.• Простота создания своих модулей (привет ExtUtils::MakeMaker).

Что, по-твоему, является самой важной особенностью языков будущего?

Перестать опускать планку порога вхождения в язык. Я прекрасно понимаю,что рынку не хватает программистов. Также я понимаю, что всем хочетсяпрограммировать. Однако, это не повод упрощать инструменты до уровня,понятного и дебилу. Сложность перла практически оптимальная. По моемумнению, самое последнее скотство это жертвовать функциональностью воимя снижения порога вхождения. Целевая аудитория, как правило, не вос-пользуется, а вот урезанная функциональность печалит.

Что думаешь о Perl 6?

Отличный язык. Жаль, что невовремя.

Было бы приятно, если бы взлетело, но я не понимаю двух вещей. Зачемэто назвали Perl и сколько надо затратить сил и средств, чтобы вывести егосообщество хотя-бы на уровень Perl 5. Я думаю, что использовав другое имядля языка шансов взлететь было бы сильно больше.

43

Page 48: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Интервью с Дмитрием Шаматриным

Что лучше: работать на аутсорс или на продукт?

Тут нет однозначного ответа. Мне интереснее продукт, например, хотя, вро-де как, по статистике, аутсорс стабильнее. Короче. Аутсорс — меньше рисков,низкая вероятность большого профита в будущем. Продукт — риски, кото-рые, в основном, от тебя не зависят. Ну, например, бабло закончилось. В слу-чае успеха можно получить некислую материальную выгоду.

Как жить программисту, если кажется, что вокруг одни дураки?

Понять и простить. Правило 95% непобедимо.

Если же вопрос стоит о том, что делать с коллегами по цеху, которые по темили иным причинам сейчас знают меньше тебя, то ответ прост и он един-ственно верный: обучать других и обучаться самому. Я, например, если комне обращаются с вопросами, стараюсь по мере сил помогать всем. Если лю-ди учиться не хотят, то все плохо, и надо что-то менять. Вообще, чем вышесуммарный уровень квалификации в хорошо слаженной команде, тем про-ще жить всем.

Лучше специализация или везде по чуть-чуть?

А это смотря что хочется делать и что делаешь. Если ты занимаешь пози-цию техлида и решаешь проблемы в определенном и ограниченном спектрезадач (например, в телекоме), то тут сильно лучше иметь узкую специали-зацию. Если же твоя задача рулить разработкой большого проекта, то спе-циализация ок, но куда важнее быстро разобраться в текущей задаче, а этотребует везде по чуть-чуть. Особенно, это касается тех случаев, когда необ-ходимо принимать серьезные технические решения, от которых много чегозависит или будет зависеть.

Так все-таки Erlang или Haskell?

Они решают примерно подобные задачи.

Эрланг позволяет довольно быстро построить приложение, которое будетустойчиво к рантайм-ошибкам, которых, как все мы знаем, предостаточновсегда. Причем, 90% этих ошибок случается хрен пойми почему. К тому же,будучи функциональным языком, он позволяет делегировать некоторыесложные вещи виртуальной машине и сосредоточиться на реализации. Им-

44

Page 49: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Интервью с Дмитрием Шаматриным

мутабельные переменные, хорошая многопоточность. Ну и OTP. Все вместеэто дает реально хороший, но при этом несложный язык, который оченьхорошо работает под нагрузкой, редко падает и довольно неплохо масшта-бируется. Ну, если просто и на чистоту, то эрланг правильно используетраззвиздяйство программиста, культивируя три основные добродетели. Даи очень идеологически близок к перлу.

Хаскель позволяет делать практически то же самое, но при этом сильно слож-нее и дороже, что требует больше ресурсов. Ну и сложная система типов по-началу будет сильно взрывать мозг. Мой совет — учите оба :D Потому какпонимание хаскеля, как чистого функционального языка, в конечном итоге,позволяет намного лучше писать на эрланге.

Сколько времени проводишь за написанием Perl-кода?

Когда как. Обычно несколько часов в день.

Стоит ли советовать молодым программистам учить сейчас Perl?

Стоит. То, что перл сейчас каждый год закапывают, а код на нем нечитаеми плох, есть следствие следующего забавного парадокса: в то время, когдапоявился перл, не было ничего, с чем бы он серьезно конкурировал в ни-ше, например, сайтостроения. К тому же, культуры программирования, кактаковой, тоже, в широких массах, особо не было. Соответственно, весь тоткод, за которые клеймят Perl, это не вина языка. Если бы в то же время по-явился, например, питон или руби, сейчас бы слава worn-языка была бы уодного из них. Просто не в то время. Почему стоит учить? Да потому, чтоон достаточно низкоуровневый, чтобы разобраться, как работают файловыедескрипторы, сокеты, счетчик ссылок. И он достаточно высокоуровневый,чтобы разобраться с концепциями в мире современного программирования.Ну и имеет очень большую базу библиотек, да.

Вопросы от читателей

Будут еще хакатоны и конференции?

Будут и много. Скорее всего что-то проведем летом. Есть в планах одесскаяконференция по функциональному программированию.

Какой веб-фреймворк сейчас стоит использовать и почему?

45

Page 50: Pragmatic 34 Perlpragmaticperl.com/issues/34/pragmaticperl-34-a4.pdf · 2015. 12. 31. · ВпечатленияотворкшопаSaintPerl2015 2. ВпечатленияотворкшопаSaintPerl2015

Интервью с Дмитрием Шаматриным

Мне в последнее время очень нравится перловыйCatalyst. Почему? Удобный,много умеет, под него написано очень много модулей. Ну и еще очень нема-ловажный момент — адекватный мейнтейнер. Минусы — громоздкий.

■ Вячеслав Тихановский

46