Perl для очень ленивых

     Многим знаком язык скриптового программирования Perl. О его достоинствах и недостатках можно спорить долго, но в сети он приобрел изрядную популярность и множество поклонников. Я хоть и не вхожу в их число, но не могу не признать, что для ряда задач он является очень удобным, хотя бы из-за наличия большого количества бесплатных библиотек для работы с графическими форматами, сетями и т.д. В частности, в нем довольно неплохо организована работа с документами PDF. Сам синтаксис языка тоже достаточно близок к основным языкам программирования. Во всяком случае, настолько близок, чтобы человек, имеющий опыт программирования, мог, без недельного ускоренного курса обучения, сесть и сходу поправить пару строк в готовой программе или даже, погуглив в сети минут десять по специализированным сайтам и форумам, набросать простенькую консольную утилиту для внутреннего пользования, скажем, для перекодирования файла или конвертирования одного формата в другой. Единственная беда заключается в том, что для того, чтобы данная программа заработала, придется совершать еще массу телодвижений, мучительных для программиста-любителя, разбалованного GUI и отвыкшего от консольного программирования. В частности, нужно найти и установить сам Perl, нужные библиотеки нужных версий, разобраться в процессе компиляции и исполнения и все в режиме командной строки, столь неудобном в нынешних графических операционных системах. Перенос программы на другой компьютер тоже сопряжен с головной болью - ведь, для полноценной работы скрипта на другом компьютере, необходимо установить интерпретатор со всеми требуемыми библиотеками и на него тоже. Что, иной раз, превращается в серьезную проблему. К примеру, как объяснить пользователю, программистом не являющимся по определению, что для корректной работы, в срочном порядке набросанного патча из двух строк, ему требуется найти в сети и установить весьма увесистый пакет, из которого потом этот патч запускается в режиме командной строки? Особенно, если до этого пользователь вообще не представлял себе, что консольный режим существует. К счастью, последняя проблема более-менее решаема: perl предоставляет средства для сборки своих скриптов в единое исполняемое EXE приложение, которое можно запускать на любом компьютере, не заботясь о предварительной установке туда интерпретатора и библиотек. К примеру, это пакеты PAR (вдобавок, бесплатный) или perl2EXE. Принцип действия таких пакетов прост - они представляют собой, в некотором роде, саморазворачивающийся архив, в котором упакованны скрипт, интерпретатор и библиотеки. При запуске такого EXE файла, все содержимое незаметно разархивируется в системный временный каталог и интерпретатор оттуда запускает файл скрипта. Данный процесс проходит достаточно шустро, да и сам исполняемый модуль весит немного, поэтому получается простая и компактная консольная утилита (или не консольная, все зависит от степени продвинутости программиста и его способности прикрутить к ней GUI). Процесс изготовления такой утилиты для начинающего разработчика можно упростить еще сильнее, если исходить из того, что каждый исполняемый модуль, полученный таким методом - это архив. В первую очередь из этого следует, что из готового EXE модуля можно распаковать исходники в явном виде, поменять на свои и запаковать обратно. При этом выходит, что даже для разработки приложений, устанавливать весь пакет Perl и библиотеки на свой компьютер вовсе не надо, как и разбираться в достаточно муторном и нетривиальном процессе компиляции - мечта ленивого программиста. В идеале самым желанным был бы случай, когда пользователь открывал бы готовый EXE файл стандартным архиватором, подправлял нужный текстовый модуль и автоматически запаковывал его обратно, получая на выходе уже приложение со своими функциями. Конечно же, такая наглость в полном объеме невозможна, однако, можно попытаться приблизиться к идеалу. Оставим в стороне случай perl2exe и других коммерческих компиляторов и обфускаторов, из соображений лицензионности и конфиденциальности кода, хотя и в этих случаях существуют определенные решения. Рассмотрим простейший и наиболее распространенный бесплатный упаковщик PAR. EXE, упакованный им представляет собой обычный ZIP архив с прикленным загрузчиком в начале и маленьким довеском в конце, содержащим указатель на начало увакованных данных. Его ZIPовая природа настолько явна, что бесплатный архиватор 7-Zip сразу распознает в нем архив и открывает его. Более того, старые версии этого архиватора умели не просто открывать и распаковывать файлы из такого EXE модуля, но и добавлять исправленные файлы обратно. К сожалению, перепакованный таким образом EXE файл переставал корректно запускаться, поскольку отсутствовал необходимый довесок в конце, без которого интерпретатор, естественно, не работал. В более поздних версиях 7-Zip возможность исправления и добавления файлов в исполняемые PAR модули была, по этой причине, заблокирована вообще, но, к счастью, распаковывать файлы оттуда все равно можно. Итак, мы имеем возможность, воспользовавшись архиватором 7-Zip, получить все исходники и используемые библиотеки исполняемого модуля в прямом явном виде. Далее, можно, конечно, пользуясь установленными пакетами Perl и PAR честно скомпилировать из исходников новый EXE, но зачем? Как было сказано выше, мы ищем легкий путь для ленивых, в котором наличие установленного Perl вообще не требуется. Для начала, ищем в распакованных через 7-zip исходниках главный модуль и заменяем его на свой. Сделать это достаточно просто. После распаковки мы, помимо манифеста, получаем два подкаталога с перловскими текстовыми файлами - lib и scripts:

Согласно здравому смыслу, нужный нам файл находится в каталоге scripts. Заходим туда, и точно - видим два файла: main.pl и еще один модуль, обычно, одноименный с EXE. Это и есть исполняемый perl скрипт, поэтому, убираем оттуда весь код, оставляя, естественно, подключения библиотек. По традиции, в качестве примера, приведу завязший у всех в зубах код Hello world:

use warnings;

use strict;

use Win32;

Win32::MsgBox("Hello, world!", 64);

После чего сворачиваем архиватором распакованные каталоги в обычный ZIP файл, компрессия не имеет значения, единственно что необходимо, чтобы в архиве сохранялась структура подкаталогов. Осталось дело за малым - приклеить к полученному архиву начало в виде запускающего модуля и хвост, содержащий ссылку на упакованные данные. Для простоты я набросал маленькую утилитку, которая это делает автоматически. Запускаем ее, указываем путь к архиву и результирующему EXE модулю и, бинго! Мы получили свою первую EXE программу на perl без использования самого пакета perl и даже не имея ни малейшего понятия о его синтаксисе и принципах программирования на нем. Мечта ленивого программиста осуществилась.