ЧАСТЬ 8. Последняя. Это последняя часть опуса "Hello, Perl!", посвященного "ЧастоЗадаваемымВопросам" по программированию на языке Perl. В этой части мы рассмотрим несколько полезных, с моей точки зрения, модулей. На некоторых из них остановимся подробнее.
"Не виноватая я!..." Когда возникают ошибки в скрипте, может оказаться полезным действием проверка переменных окружения, состояния HTTP-заголовков и т.п. С проверкой переменных окружения сервера проблем возникнуть не должно.
#!/path/to/perl print "Content-type:text/html\n\n"; grep print("$_=$ENV{$_} "), keys %ENV;
С помощью LWP можно проверить и полный HTTP-ответ сервера клиенту. Эти данные можно взять из $result->status_line и $result->headers_as_string(). Но самое сложное - проверить, что передает броузер.
Для этого нам необходимо написать свой сервер. Нет ничего проще!
use Socket; # Открываем потоковый (STREAM) сокет для протокола tcp socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); # Опции сокета. Чтобы не было тайм-аута между запусками сервера setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, 1); # Привязываем дескриптор к порту и локальному адресу. # Эта функция регистрирует сервер bind(SOCK,sockaddr_in(80,INADDR_ANY)); # Ставим очередь на подключение с максимальным кол-вом подключений listen(SOCK,SOMAXCONN); print "Socket OK\n"; if(accept(CLNT,SOCK)){ # Если клиент с нами соединился print "Client accepted\n"; open(F,">request.txt"); while($line=){ # Читаем, что он пишет до "\n\n", и записываем в файл $line=~s/\r//g; last if $line eq "\n"; print F $line; } print "Client data OK\n"; close(F); print CLNT "HTTP/1.0 200 OK Found\n". # Пишем ему ответ "Accept-Ranges: bytes". "Keep-Alive: timeout=15". "Connection: Keep-Alive". "Content-Length: 15". "Content-type:text/plain\n\n". "Hello!"; print "Session finished"; close(CLNT); # Закрываем все сокеты и выгружаемся close(SOCK); exit; } # если вместо if(accept) while (и не закрывать сокет), то сервер не будет ждать # запросов и по очереди их обрабатывать.
Теперь в файле request.txt лежит запрос, посланный броузером, и мы можем узнать, соответствует ли он принятым стандартам ;-). Ну и для примера напишем еще клиента для проверки ответа сервера, но уже с помощью IO::Socket;
use IO::Socket;
$sock=IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 80, Proto => 'tcp', Type => SOCK_STREAM); print $sock "GET / HTTP/1.0\n". "User-Agent:Murzilla 3000\n". "Connection: Keep-Alive\n\n"; open(F,">server_response.txt"); while($line=<$sock>){ $line=~s/\r//g; next if $line eq "\n"; print F $line; } close(F); close($sock);
В файле server_response.txt будет ответ.
Теперь продолжим обзор других модулей.
Файловая рекурсия. Часто в программировании возникают задачи, требующие перебора целого дерева файлов. В этом случае без рекурсии обойтись практически невозможно. Что такое "рекурсия"?. Проще говоря, это когда какая-либо функция вызывает сама себя.
# %H - сложный многомерный хэш hash_tree(\%H, 0); # Передаем ссылку в функцию и уровень вложенности 0 sub hash_tree{ my($ref,$num)=@_; if(ref $ref){ # Если значение - ссылка, увеличиваем уровень на 1 $num++; for(keys %$ref){ # И для каждого элемента по ссылке вызываем сами себя hash_tree($ref,$num); } }else{ # Если значение - не ссылка, пишем его со сдвигом слева, # в зависимости от глубины вложенности $num print ' ' x $num; print "$ref\n"; } }
Чтобы не изобретать велосипед, для перебора файлового дерева можно воспользоваться модулем File::Recurse
use File::Recurse; $MAX_DEPTH=100 # Глубина. По умолчанию - 100 $FOLLOW_SYMLINKS=0 # Следовать ли символическим ссылкам? По умолчанию - 0 (нет) recurse { chmod 0666, $_ } "/home/users/vasya/public_files";
Опять картинки. Если вам нужно определить размер картинки или свойства GIF-файла или сграбить кучу картинок с сайта, то Вы можете воспльзоваться семейством модулей Image::***.
Image::Grab - Картинки из сети Image::ParseGIF - Разбор гифа Image::Size - Размер Image::Magick - Рисовалка
Процессы. Для того чтобы манипулировать процессами, открывать файлы на запись и чтение (программы тоже), в Perl имеется множество возможностей. Кроме стандартного fork (который не работает в Win32) есть модули семейств IPC (InterProcessCommunication), Proc::***, Win32::Process, etc.
IPC::Open2 - Открытие (запуск) файла на чтение и запись IPC::Open3 - То же, но еще с потоком для ошибок Proc::Background - Процессы в "задней земле" ;-) Proc::*** - Всяческие манипуляции с процессами Win32::Process - Процессы в Win-системах Parallel::ForkManager - Название говорит за себя
Вот пример, взятый из Perl CookBook, показывающий, как запустить приложение Perl/Tk без окна DOS
use Win32; use Win32::Process; Win32::Process::Create($Win32::-Process::Create::ProcessObj, 'd:\perl\bin\perl.exe', # Путь к Перлу 'perl ./GUIperldoc.pl', # Строка запуска "perl имяПрограммы" 0,DETACHED_PROCESS,".")|| die Win32::FormatMessage(Win32:-:GetLastError());
Снова про Сеть. Для получения какой-либо полезной информации из Сети, кроме различных модулей типа Mail::***, News::*** и т.п., в Perl имеются модули, являющиеся практически готовыми клиентскими программами, предоставляющими разработчику скриптов свой интерфейс. Я говорю о модулях семейств WebFetch::*** и WWW::Search::***. WebFetch - это модули для скачивания различных новостей и т.п. информации. Например, WebFetch:: DebianNews, WebFetch::PerlStruct и другие. Название расширения WebFetch::*** говорит само за себя. То же относится и к расширениям WWW::Search:::***.
WWW::Search::AltaVista - Работа с поисковиком WWW::Search::Excite - - || - WWW::Search::Google - - || -
Кроме того, модули WWW::*** помогут вам написать робота, работать с WWW-конференциями и т.д.
Проверим, есть ли в поисковике Altavista ссылки на perl.ru =)
use WWW::Search; $search = new WWW::Search('AltaVista'); $search->native_query(WWW::Search-::escape_query("\"perl.ru\"")); while (my $result = $search->next_result()){ print $result->title, "\n", $result->url, "\n\n"; } Regexp. Для того чтобы создать регулярное выражение для определенного списка строк, можно это сделать вручную. Но если знаний в области regexp маловато и список слишком велик, то воспользуйтесь модулем Regex::PreSuf. Вот пример из документации по этому модулю: use Regex::PreSuf; $re = presuf(qw(foobar fooxar foozap)); print $re;
Еще один полезный модуль - Regexp::Shellish - регулярные выражения а-ля консоль. А вы не знали, что в консоли есть регексп? Теперь знаете ;-)
Работа с Win32. Для работы в Win32 есть большое семейство Win32::***. Кроме того, есть модули Win32API, Script, etc. Модули Win32::*** предоставляют широкий интерфейс для программирования приложений под эту ОС. Здесь есть возможности работы с реестром, WinAPI, OLE, DDE, ASP, ODBC, файловой системой, процессами, сервисами, возможности администрирования и многое другое. Модуль Script - это модуль для написания административных скриптов для управления логином системы, запуском приложений.
# Читаем Clipboard use Win32::Clipboard; $clp = Win32::Clipboard(); print "Clipboard: ", $clp->Get(), "\n"; # Ставим атрибуты файлам use Win32::File; SetAttributes($filename, HIDDEN); # В Сети через Wininet.dll use Win32::Internet; $www = new Win32::Internet(); $url = $www->OpenURL("http://www.comprice.ru";); $html = $url->ReadFile(); $url->Close(); # Список юзеров (текущий домен) use Win32::NetAdmin qw(GetUsers); my %users; GetUsers("", FILTER_NORMAL_ACCOUNT , \%users); grep print("User:$_ Name:$users{$_}\n"), keys %users; # Список сервисов (NT only) use Win32::Service; GetServices("",\%servs); grep print("Service:$_ Name:$servs{$_}\n"), keys %servs; # Играем музыку use Win32::Sound; Win32::Sound::Volume('100%'); Win32::Sound::Play("supermusic.wav"); Win32::Sound::Stop(); # Работаем с MS Excel через OLE (Лучше Perl, чем экселевские макросы ;-)) use Win32::OLE; $xlfile="E:\\Programming\\-Perl\\XL\\test.xls"; $xl=Win32::OLE->GetObject($xlfile); $sheet=$xl->Worksheets(1); $sheet->Cells(1,1)->{Value}="Hello,Perl!"; $sheet->Range("A2:C2")->{Value}=(["PerlFAQ", "by cmauk[0nline]" ,"cmapuk\@pisem.net"]) $sheet->SaveAs("newtest.xls");
Так что Perl - это не только Unix, как думают многие. C помощью этих модулей можно автоматизировать рабочие процессы (c Excel, Access и другие), администрирование и многое другое. Всяко-разно
MP3::Tag - Модуль для манипуляций с тэгами в mp3-файлах. В этих тэгах содержится такая информация, как название композиции, автор и прочее. Если вы храните на сайте mp3-файлы - этот модуль вам будет полезным =).
use MP3::Tag; $mp3 = MP3::Tag->new($filename); $mp3->getTags; print $mp3->{ID3v1}->song; PostScript::*** - модули для работы с PostScript-файлами. Для тех, кто занимается паблишингом и не только. Sort::*** - модули для всевозможной сортировки. Очень полезны. @lines=("010 Vasya Pupkin user", "010 Pasha Urodov master", "010 Kevin Mitnikov admin", "010 Masha Pupkina user"); use Sort::Fields; @sorted = fieldsort [3], @lines; print join("\n",@sorted);
Вот так можно отсортировать строки по третьему слову, в данном случае по фамилии.
Spreadsheet::*** - Модули для работы с файлами Excel Term::*** - Семейство модулей для работы с терминалом. Цветной вывод, чтение символа после нажатия клавиши и тому подобные возможности. URI::*** - модули для манипуляций с адресами. Поиск адресов в тексте, разбор адреса, управление букмарками Нетскейпа и многое другое. VRML::*** - Для тех, кто занимается моделированием виртуальной реальности на языке VRML. Есть возможности работать как с VRML1.0, так и с версией 2.0 этого языка. XBase - Интерфейс к dbf-файлам баз данных. Простой и удобный интерфейс. XML::*** - Большое семейство модулей для работы со стандартом XML. XML::Generator - Генератор XML XML::Parser - Парсер XML-данных XML::Writer - Писать XML-файлы use XML::Writer;use IO; my $output = new IO::File(">output.xml"); my $writer = new XML::Writer(OUTPUT => $output); $writer->startTag("hello", "class" => "simple"); $writer->characters("Hello, Perl!"); $writer->endTag("hello"); $writer->end(); $output->close();
Ну все. Хорошего понемножку. PerlFAQ по-русски версии 1.0 закончен. Жду предложений, пожеланий, критики и другой полезной информации на e-mail. В этой статье рассмотрены далеко не все вопросы о Perl, в частности о Regexp. Это оставим для следующих версий. А пока, присылайте комментарии.
Спасибо за внимание.
При написании статьи использовались материалы из документации Perldoc, книги "Perl Cook Book".
По материалам журнала Компьютер Price (www.comprice.ru)
|