Типы данных в perl. Доступ к переменным окружения

FAQ по языку Perl для начинающих

Часто задаваемые вопросы, собранные в конференции RU.CGI.PERL.CHAINIK Что такое CGI? Это общий интерфейс шлюзов, связывающий программу, работющую под управлением вебсервера и клиента в виде HTTP-браузера. Иными словами, это средство, которое позволяет генерить HTML-документы "на лету", в зависимости от условий и пожеланий программиста. Как и любое клиент-серверное средство, CGI-программа состоит из двух частей - одной, которая работает на клиенте, в среде браузера, и другой, работающей на сервере, в среде вебсервера. Клиентская часть пишется на HTML (возможно, с употреблением раздичных дополнительных средств, расширяющих его возможности), серверная часть может быть на- писана на любом языке программирования, способном создавать выполняе- мые программы на платформе, на которой установлен вебсервер. Мы будем использовать для этих целей Перл, потому что он удобен для обработки текстовых строк - а HTML документ представляет собой именно текст. Принцип работы интерфейса очень прост - вебсервер, если ему это разрешено, может запустить выполняемую программу; в отличие от запуска этой же программы пользователем потоки вода, вывода и ошибок запущен- ной программы будут перенаправлены: ввода и вывода в протокол HTTP, а ошибок - в файл лога ошибок вебсервера. Таким образом, мы можем созда- вать HTML-документ "на лету", просто выводя в поток вывода его теги с помощию команды print или ее аналога. Впрочем, лучше один раз увидеть, чем сто раз услышать. Для того, чтобы работать с клиент-серверными пограммами, нужно сначала устано- вить клиент и сервер. В качестве клиента может быть использован любой браузер, поддерживающий протокол HTTP (рекомендуется Netscape, потому что он достаточно строго реагирует на ошибки; можно быть увереным, что то, что работает в нем будет работать где угодно - а обратное выполня- ется редко), в качестве сервера рекомендуется вебсервер Apache. Это один из самых распространенных вебсерверов, он может быть скомпилиро- ван полд все мыслимые платформы и ситемы, и отладженные под него прог- раммы скорее всего сможет установить любой провайдер. Вебсервер Apache для Windows лучше всего получить по адресу ftp://cdl.bmstu.ru/soft/cgi . Установите его, однако не в директорию, которую он предлагает для установки, а в c:\apache . Вебсервер может работать и в том случае, если он установлен в руть по-умолчанию, одна- ко при его настройке возникнут некоторые разночтения с предлагаемым здесь вариантом - если Вы хотите избегнуть нежелательных осложнений, измените путь по-умолчанию. Запустите вебсервер (на экране появится пустое черное окно - это нормальный результат успешного запуска; ни в коем случае не закрывайте это окно принудительно - для финиширования вебсервер создал Вам специ- альную иконку). Обратитесь к нему из браузера через URL http://localhost и убедитесь, что демонстрационная веб-страница, кото- рая находится в директори htdocs успешно запускается. Если вебсервер не удалось запустить, прочитайте выводимое им со- общение об ошибке. Чаще всего вебсервер не может запуститься из-за то- го, что не указано имя. Откройте на редактирование основной файл кон- фигурации вебсервера (httpd.conf) и снимите ремарку с пересенной Servername, присвоив серверу любое имя - например localhost. Теперь имеет смысл попробовать выполнить первую CGI-программу. Для того, чтобы иметь возможность писать CGI-программы на Перле, следует установить Перл. Взять его можно там же, где и вебсервер, ус- тановка этой программы не содержит особых подводных камней. Вам будет предложено скомпиллировать Перл из текста на Си, если Вы откажетесь от этого (что рекомендуется), будет развернута уже скомпилированная би- нарная версия. После установки не забудьте проложить в файле Autoexec.bat путь в директорию c:\perl\bin - туда, где содержится файл perl.exe. Проверьте правильность установки Перла, написав простейшую прог- рамму, состоящую из одной строки: print "Hello"; Запустите эту программу из любой директории, набрав "perl filename", где filename - имя файла, в который Вы вписали приведенную выше строчку. Если на экране появилось слово Hello, это ззначит что Вы все сделали правильно. В отличие от многих других вебсерверов, Апач сам вызывет интерп- ретатор Перла, таким образом в каждой программе нужно указывать, где он находиться. Таким образом, первой строчкой нашего CGI-скрипта дол- жен быть путь к интерпретатору: #!perl после того, как путь к интерпретатору указан, нужно выставить серверный http-заголовок, указывающий тип отдаваемых данных: Обратите внимание, что поле http-заголовков завершается двойным переводом строки. Сами заголовки, если их несколько, отделяются друг от друга одинарным переводом строки. Третья строчка нашей программы будет содержать необходимую для создания html-документов обвеску: print "";
print "";
print " VLINK=\"#551A8B\">\n";
Обратите внимание, что при использовании внутри команды print, двойные кавычки необходимо отчеркивать - иначе интерпретатор примет кавычки за окончание команды, а то, чт о идет после них - за незавер- шенную строку, и ответит ошибкой выполнения. Теперь необходимо вести строчку вывода, и закрыть html-докумнт. print "Hello";
print "";
Таким образом, вся наша первая программа будет выглядеть так: #!perl
print "Content-type: text/html\n\n";
print "";
print "";
print "\n";
print "Hello";
print "";
Проверьте правильность ее выполнения, запустив программу локаль- но. Для этого наберите в командной строке: perl filename, где filename - это имя Вашей программы. Если все в порядке, программа должна напи- сать на экране http-заголовок, а затем теги html-документа, который программа создает. После локальной проверки нужно запустить программу как кли- ент-серверное приложение. Для этого нужно дать программе права на вы- полнение (для операционых систем, где это актуально), и расположить в директории, в которой вебсервер распознает програмы как CGI-приложе- ния. По умолчанию, это директория cgi-bin, в которой и надо разместить нашу программу. Для запуска программы нужно набрать в окне location ее URL: http://localhost/cgi-bin/filename Как передавать данные между клиентом и сервером? Как передать данные с сервера на клиент мы уже рассмотрели. Сле- дующим шагом представляется передача данных с клиента на сервер и фор- мирование клиента с учетом переданной на сервер информации. Существуют несколько МЕТОДОВ, с помощью которых можно передать информацию на сервер; самые распространенные из них - это метод GET, передающий данные в URL и метод POST, передающий данные в теле запро- са. Недостатком первого является ограниченный объем передоваемой ин- формации (до 127 байт), недостатком виторого - сложность в формирова- нии запроса. В самом деле, чтобы сформировать запрос методом GET вполне доста- точно написать знак вопроса после URL вызова, и перечислять через ам- персанд пары "имя=значение": http://localhost/cgi-bin/test2.cgi?v1=vasya&v2=petya и так далее. Теперь нужно получить эти данные на сервере, для чего достаточно полу- чить содержимое переменной окружения вебсервера QWERY-STRING. Эта пе- ременная содержит то, что в URL располагалось после знака вопроса. Есть, однако, одна особенность, которая делает затруднительной использование этой переменнй. Дело в том, что русские буквы, как и специальные символы, в URL заперщены - поэтому их придется заменить на специальный код, который не содержит запретных символов, а просле при- ема на сервере потребуется произвести обратную перекодировку. Такая перекодировка является вполне стандартной для CGI-программирования, и в комплекте любого Перла предусмотрен модуль, который умеет читать со- ответствующую переменую, перекодировать ее содержимое и раскладывать приняные данные по переменным. Модуль, в котором содержася эти подп- рограммы называется CGI. Подключите его к своей программе, написав: use CGI qw(param); после чего Вы сможете захватывать из входного потока любую переменную, написав, к примеру: $v1=param("v1"); теперь, если Вы вызвали скрипт с помощью приведенной выше URL-и, то модуль будет искать в принятых данных переменную потока "v1", а найдя, присвоит ее значение скаляру $v1, который будет теперь равняться "vasya". Чтобы подтвердить правильность наших построений, давайте вы- полним программу, которая иллюстрирует такую передачу данных: #!perl
use CGI qw(param);
$v1=param("v1");
$v2=param("v2");
print "Content-type: text/html\n\n";
print "";
print "";
print "";
print "Hello, $v1 , $v2 !!!";
print "";

Метод POST передает данные в теле запроса, а получать их следует через входной поток программы (напомню, при запуске программы вебсер- вером он направлен в протокол HTTP). Для отсылки данных этим методом в HTML служат формы. Например, выполнив на клиенте приведенную ниже фор- му мы получим точно такой же результат, как и в предыдущем примере: <HTML>

http://localhost/cgi-bin/test3.cgi >






Модуль CGI, обрабатывающий входные данные работает совершенно одинаково как при применении метода GET, так и при использовании мето- да POST. Часто задаваемые вопросы (часть вторая) Используются некоторые материалы из "Perl FAQ created by SLY Golovanov, 2:5020/794.13" Где взять документацию по Perl? Во-первых, Perl при установке добавляет в Вашу систему команду perldoc. Выполните ее с ключем perldoc (т.е. perldoc perldoc), и она напишет как ею пользоваться. Для модулей выполняйте perldoc <имя_модуля> а для внутенних фун- кций perldoc -f <имя_функции> Во-вторых, есть кое-какие книги по Perl на русском языке: http://doc.marsu.ru/lang/perl/lama/ ftp://mshp.minsk.by/pub/incoming/lama.rar ftp://ftp.kursknet.ru/pub/books/lama_perl.zip ftp://molly.wbt.ru/incoming/lama.rar http://simplex.ru/news/ И на английском: http://solaris.inorg.chem.msu.ru/cs-books/perl/perlbookshelf.zip http://lpcs.math.msu.ru/CD_Bookshelf/Perl_content.tar.bz2 ftp://twilight.telco.md/pub/books/perlbookshelf.zip http://meltingpot.fortunecity.com/nj/80/cookbook.rar http://www.effectiveperl.com http://www.perlreference.com http://perlfect.com/articles/ http://www.perlmonth.com/ http://www.stonehenge.com/merlyn/WebTechniques/ http://www.stonehenge.com/merlyn/UnixReview/ http://www.stonehenge.com/merlyn/LinuxMag/ http://www.plover.com/~mjd/perl/#tpj http://home.od.ua/watman/perl/ http://spider.softclub.net/books/web/ http://athena.vvsu.ru:85/docs/unix/ http://athena.vvsu.ru:85/docs/tcpip/ http://athena.vvsu.ru:85/docs/www/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% А вот здесь можно взять готовые скрипты самого разного назначения: www.script.ru www.codemanual.com %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Что делать, если Ваш скрипт постоянно выдает код завершения номер 500 (внут- ренняя ошибка сервера)? 1. Попробуйте запустить программу локально, для чего наберите в коман- дной строке: perl filename (где filename это сами понимаете что). Обратите внимание, что если вы работаете в Юникс-системе, где кроме уста- новленного Вами пятого перла наверное есть еще и встроенный четвертый, и не факт что он расположен позже на путях, имеет смысл набирать perl5 filename потому что пятый perl как правило имеет такой псевдоним. Попытка выполнить программы с объектными модулями (к коим относится и модуль CGI) на четвертом Perl приведет к печальным последствиям. Если программу удалось запустить, посмотрите на сообщения от ошибках, ко- торые она выдает. Обратите внимание, что исправлять можно ТОЛЬКО первую из продиагностированных ошибок (остальные могут оказаться наведенными). 2. Если программа выполняется локально но не запускается сервером, про- верьте, правильно ли программа выставляет HTTP-заголовок, устанавливающий тип вывода. Для генерации HTML-документов он долже быть таким:
Убедитесь, что такая строка присутствует в Вашей программе до вывода любого символа в HTTP поток. Говоря упрощенно, эта команда print должна быть выполне- на раньше любой другой команды print. 3. Если это не принесло результата, проверьте тот ли Perl Вы вызываете. Во многих UNIX-системах четвертый Perl расположен по пути: /usr/local/perl а пятый по пути: /usr/local/bin/perl На всякий случай убедитесь, что пятый Perl в системе вообще установлен. 4. Если и это не помогает, постарайтесь вспомнить, не проходил ли файл с Вашим скриптом правки в текстовых редакторах из Windows. Разумеется, это ак- туально только в том случае, если Вы запускаете скрипт на Unix-системе. Дело в том, что у Windows и Unix различные символы конца строки. Любой встроенный в Windows редактор оперирует с концами строк стандарта Windows, при этом Unix не может выполнить такой файл. Для борьбы с таким эффектом рекомен- дуется либо создавать и редактировать файлы только в Unix-системах, либо соз- давать и редактировать их в Windows только встроенным редактором менеджера FAR, который позволяет выбирать тип создаваемого файла через нажатие shift-F2. По умолчанию этот редактор использует те символы окончания строк, которые уже есть в файле (то есть созданный в UNIX файл можно сохранять "как есть", не за- думываясь о его типе). Если Ваш скрипт уже создан в стандарте Windows, а Вы хотите запустить его на Unix, воспользуйтесь, например, вот такой программой: $v1 = "\x0d";
open A, "f1";
while ($line=)
{
$line =~ s/$v1//g;
$itog .= $line;
}
close A;
open B, ">f1";
print B "$itog";
close B;
Эта программа открывает на чтение файл с именем f1, расположенный по мес- ту запуска, читает оттуда по очереди все строки, заменяя окончание каждой из них. После чтения программа открывает тот же файл как новый на запись и запи- сывает в него полученый результат. 5. Как последний шанс - проверьте, имеет ли скрипт права на чтение и вы- полнение со стороны того пользователя, от которого работает вебсервер. Нет, вы все-таки это проверьте. Если Вам и это не поможет, пишите в конференцию. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Как посмотреть все переменные окружения вебсервера, активные на данный момент? for (keys %ENV) { print "$_ = ${ENV{$_}}\n" } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Что такое ключи (cookies), и для чего они нужны? Ключи - это способ открыть файл на диске клиента. Поскольку такой файл - это потенциальный вирус, эта процедура должна быть как следует защищена на уровне браузера. Ключ можно установить на время существования запущеного брау- зера или на определенный срок. Для первого типа ключей можно не указывать вре- мя, когда ключ будет удален, для второго типа нужно указать это время, причем в доступном для браузера формате. Если браузер не сможет установить в своем календаре даты, когда ключ должен быть удален, он сотрет его при первом же закрытии программы. Для того, чтобы автоматизировать процесс составления даты, применяется процедура, устанавливающая дату на месяц вперед от настоящего мо- мента: sub get_cookie_date{
my(@day, @mon, $i, $count, $sec,$min,$hours,$mday,$mon,$year, $wday, $yday,
$isdst, $result);
($sec,$min,$hours,$mday,$mon,$year, $wday, $yday, $isdst)=gmtime(time+2592000);
@day=("Sunday", "Monday", "Tuesday", "Wednesday", "Thurday", "Friday",
"Saturday");
@mon=("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
"Nov", "Dec");
if($year >= 100){
$year = $year - 100;
if($year < 10){$year = "0$year";}
}
$result=$day[$wday].", ".$mday."-".$mon[$mon]."-".$year."
".$hours.":".$min.":".$sec." GMT";
return $result;
}
Не забудьте положить в какой-либо скаляр путь к Вашей программе от корня соответсвующей области сервера. Имя программы указывать не надо, оно будет пе- редано отдельно. Например: $path = "/cgi-bin";
Теперь Вы всегда можете установить ключ, выполнив в своей программе вот такой фрагмент кода: $date=get_cookie_date();
print "Set-Cookie: login=$log; path=$path; expires=$date\n";
print "Set-Cookie: password=$pas; path=$path; expires=$date\n";

Для того, чтобы считать ключ также предусмотрена специальная процедура: sub get_cookie{
my (%cook, @temp, $i, $count, $key, $value);
(@temp)=split(/;/, $ENV{"HTTP_COOKIE"});
$count=@temp;
for ($i=0; $i<$count; $i++){
$temp[$i]=~s/ //;
($key, $value)=split(/=/, $temp[$i]);
$cook{$key}=$value;
}
return %cook;
}
После этого получить значение ключа можно, например, так: if ($ENV{HTTP_COOKIE}){$cookies=1; %cookies=get_cookie();}
else {$cookies=0;}
if ($cookies==1)
{
$login=$cookies{"login"};
$pass=$cookies{"password"};
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Как скопировать из сети какой-либо файл? Проще всего проинсталлировать на Вашу систему модуль libwww, который поз- воляет делать это. Вот пример его использования:
#!/usr/local/bin/perl
use LWP::UserAgent;
use CGI qw(header);
my $URL = "http://www.rbc.ru/kpc/topnews/news_inc.html";
my $res = LWP::UserAgent->new->request(new HTTP::Request GET => $URL);
binmode(STDOUT);
print $res->content;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Как скопировать какой-либо файл на сервер? Для этого нужно применить кодировку Multipart метода post, она позволяет передавать на сервер даже бинарные файлы, причем размер их не ограничен. К со- жалению, не все браузеры поддердживают эту кодировку. Netscape держит ее со второй версии, MSIE- с версии 3.02. Вот пример использования этого способа: #!/usr/local/bin/perl
use CGI qw(param);
$mode=param("mode");
$file=param("file");

# директория, в которые записывается принимаемый файл.
$fup = "/huge/httpd/htdocs/ufo/up";
if ($mode eq "upload")
{
print "Content-type: text/html\n\n";
@name= split(/\\/, $file);
@name= reverse (@name);
($file1) = @name;
$file_new="$fup/"."$file1";
open A, "+>$file_new";
binmode A;
binmode $file;
while ($bytesread = read($file, $buf, 1024))
{
print A $buf;
}
close A;
print "";
print "";
print "Файл успешно перенесен на сервер.
";
print "

";
print "";
print "";
print "";
print "
";
print "
";
print "";
print "";
}
elsif ($mode eq "")
{
print "Content-type: text/html\n\n";
print "";
print "";
print "

Предупреждение. Программа пересылки файлов не работает с браузера-
ми Internet Explorer версии ниже 3.2"; print "

action=\"/cgi-bin/upload.cgi\" enctype=\"multipart/form-data\"
name=\"upload\">";
print "
Upload file:
";
print "";
print "
";
print "
";
print "
";
print "
";
print "";
print "";
}
Часто задаваемые вопросы (часть третья) Как послать письмо (в UNIX-системе). Для работы с почтой в UNIX-системах традиционно используется программа Sendmail. Обращаться к ней можно непосредственно, а можно через команду mail. В любом случае, нужно сначала подготовить адреса, заменив в них символ "@" на "\@" - в противном случае программа не может быть выполнена. $as1="@";
$as2="\@";
$mails =~ s/$as1/$as2/g;
где $mails - это адрес или серия адресов, разделенных пробелами. Письма традиционно отправляются в кодировке koi-8, в которую надо пере- вести наш текст. Сделать это можно, записав тело письма, допустим, в скаляр $as4 а затем выполнив над ними следующую операцию (для перевода из кодировки 1251 в кодировку koi-8): $as4 =~
tr/АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяЁё/бвчздецъй
клмнопртуфхжигюыэящшьасБВЧЗДЕЦЪЙКЛМНОПРТУФХЖИГЮЫЭЯЩШЬАСi?/;

Open MAILL, "|mail -s \"Subject\" $mails";
# В скаляре $mails через пробел перечисляются все адреса
print MAILL "$as4"; # это тело письма
close MAILL; Используя программу Sendmail можно посылать письмо следующим образом: open(MAIL, "|/usr/lib/sendmail -f $from_addr $mails");
print MAIL "Subject: subject_text\n";
print MAIL "content-type: text/html; charset=koi8-r\n\n";
print MAIL "To: $user <$to_addr>\n"; # На какой адрес отвечать.
print MAIL "$as4";
close MAIL;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Как прочитать принятое письмо? Самый простой способ, это использование библиотеки mail. #!/usr/local/bin/perl
use Mail::POP3Client;
$pop = new Mail::POP3Client("login", "password", "mail.server.ru");
for ($i = 1; $i <= $pop->Count; $i++) {
$bbb = $pop->Body($i);
$aaa = $pop->Head($i);
foreach ($pop->Head($i)) {/^(From|Subject): / and print $_, "\n";}
# $pop->Delete($i); #так удаляют прочитанное письмо
print "$aaa \n";
print "$bbb \n";
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LWP FAQ by Paul Kulchenko (
[email protected]), updated 03/04/2000 Это описание модуля LWP (иногда называемого LibWWW), содержащего множество весьма полезных функций. ==================================================================== 1.1. How to get text file (http, ftp)? 1.2. How to get jpeg/gif/bmp file and return it? 1.3. How to access password protected file? 1.4. How to set up REFERER and other HTTP header parameters? 1.5. How to get specified part of file (first MAXSIZE bytes)? 1.6. How to get and set up cookies? 1.7. How to specify proxy servers? 1.8. How to check for redirect? 1.9. How to create parameters for POST method? ==================================================================== 1.1. How to get text file (http, ftp)? Как получить файл через http или ftp use LWP::UserAgent;

My $URL = " http://www.yahoo.com/ ";
my $res = LWP::UserAgent->new->request(new HTTP::Request GET => $URL);
print header, $res->is_success ? $res->content: $res->status_line;
==================================================================== 1.2. How to get jpeg/gif/bmp file and return it? Как получить картинку. use LWP::UserAgent;
use CGI qw(header -no_debug);
$URL ="
http://a100.g.akamaitech.net/7/100/70/0001/www.fool.com/art/new/butts/go99 .
gif";
my $res = LWP::UserAgent->new->request(new HTTP::Request GET => $URL);
binmode(STDOUT);
print $res->is_success ? (header("image/gif"), $res->content)
: (header("text/html"), $res->status_line);
==================================================================== 1.3. How to access password protected file? Как ввести пароль. BEGIN {
package RequestAgent;
use LWP::UserAgent;
@ISA = qw(LWP::UserAgent);

Sub new { LWP::UserAgent::new(@_); }
sub get_basic_credentials { return "user", "password" }
}
use CGI qw(header -no_debug);

My $res = RequestAgent->new->request(new HTTP::Request GET => $URL);
print header, $res->is_success ? $res->content: $res->status_line;
==================================================================== 1.4. How to set up REFERER and other HTTP header parameters? Как установить переменные окружения сеанса. use LWP::UserAgent;
use HTTP::Headers;
use CGI qw(header -no_debug);

My $URL = " http://localhost/cgi-bin/hello.cgi ";
my $res = LWP::UserAgent->new->request(
new HTTP::Request(
GET => $URL,
new HTTP::Headers referer => "
http://www.yahoo.com "),
);
print header, $res->is_success ? $res->content: $res->status_line;
==================================================================== 1.5. How to get specified part of file (first MAXSIZE bytes)? Как получить часть файла. use LWP::UserAgent;
use CGI qw(header -no_debug);

My $URL = " http://www.yahoo.com/ ";
my $MAXSIZE = 1024;

Print header;
my $res = LWP::UserAgent->new->request(
new HTTP::Request(GET => $URL), \&callback, $MAXSIZE);

Sub callback { my($data, $response, $protocol) = @_; print $data; die }
==================================================================== 1.6. How to get and set up cookies? Как установить и считать ключ. use LWP::UserAgent;
use CGI qw(header -no_debug);
use HTTP::Cookies;

My $URL = "http://mail.yahoo.com/";

My $ua = new LWP::UserAgent;
my $res = $ua->request(new HTTP::Request GET => $URL);
my $cookie_jar = new HTTP::Cookies;
$cookie_jar->extract_cookies($res);

Print header;
if ($res->is_success) {
my $req = new HTTP::Request GET => $URL;
$cookie_jar->add_cookie_header($req);
$res = $ua->request($req);
print $res->is_success ? $res->as_string: $res->status_line;
} else {
print $res->status_line;
}
==================================================================== 1.7. How to specify proxy servers? Как работать через прокси. use LWP::UserAgent;
use CGI qw(header -no_debug);

My $URL = " http://www.yahoo.com/ ";
my $ua = new LWP::UserAgent;

$ua->proxy(["http", "ftp"], " http://proxy.sn.no:8001/ ");
$ua->proxy("gopher", "
http://proxy.sn.no:8001/ ");

My $res = $ua->request(new HTTP::Request GET => $URL);
print header, $res->is_success ? $res->content: $res->status_line;
==================================================================== 1.8. How to check for redirect? Как сделать редирект use LWP::UserAgent;
use CGI qw(header -no_debug);

My $URL = " http://www.yahoo.com/ ";
my $res = LWP::UserAgent->new->request(new HTTP::Request GET => $URL);

Print header;
print $res->request->url if $res->previous->is_redirect;
==================================================================== 1.9. How to create parameters for POST method? Как отправить запрос методом POST без помощи формы. use URI::URL;
use HTTP::Request;
use LWP::UserAgent;
use CGI qw(header -no_debug);

My $URL = " http://yahoo.com/?login=mylogin&password=mypassword ";
my $uri = new URI $URL;
my $method = "POST";

My $request;
if (uc($method) eq "POST") {
my $query = $uri->query;
(my $url = $uri->as_string) =~ s/\?$query$//;
$request = new HTTP::Request ($method, $url);
$request->header("Content-Type" => "application/x-www-form-urlencoded");
$request->content($query);
} else {
$request = new HTTP::Request ($method, $uri->as_string);
};

# add Host field as required in HTTP/1.1
$request->header(Host => $uri->host_port) if $uri->scheme ne "file";

My $res = LWP::UserAgent->new->request($request);

Print header, $res->is_success ? $res->content: $res->status_line;
====================================================================

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

Одно значение называется скалярной величиной или просто скаляром. Ниже приведены примеры скалярных значений, которые используются в языке Perl:
- Десятичные: 127 или 127.0 или 1.27Е2
- Шестнадцатиричные: Ox7F или 0x7f
- Восьмеричные: 0177 (первый 0 указывает, что используется восьмеричное число)
- Строка: "Hello World\n" или "Hello World"

Например, следующая команда использует отладчик Perl для того,чтобы вывести число 0177 восьмеричной системы, соответствующеечислу 127 десятичной:

DB<4> р 0177 127

Perl переводит данные в свой внутренний формат. Когда Perl печатает восьмеричные или шестнадцатиричные значения, он сначала переводит их в десятичный формат, как было показано.

Примечание: Как вы узнаете, скрипт Perl позволяет использовать функцию printf для того, чтобы выводить, значения в вызываемом формате, в таком как восьмеричный или шестнадцатиричный.

В качестве внутреннего представления всех чисел используется формат с плавающей запятой двойной точности (double). Иными словами, среди внутренних форматов нет целочисленного. Тем не менее, в большинстве случаев вы можете не обращать на это внимания, и Perl сделает все сам как надо. Например, если вы используете величины в контексте, где только целочисленные значения имеют смысл, Perl сам автоматически усечет число.

Примечание: Если вы программируете на С и использовали целочисленное деление с усечением целых чисел автоматически, то, программируя на языке Perl, надо не забыть выполнить усечение вручную, используя функцию int().

Следующая команда иллюстрирует, как Perl обрабатывает числа целого типа и с плавающей запятой:

Print 6 & 3; # выведет 2 print 6.9 & 3.1 # print 7 / 2 # выведет 2.3333 не целое print int(7/3) # выведет 2

Точно так же, как Perl преобразует числа с плавающей запятой в целые числа: когда скрипт использует целочисленные значения, он также преобразует числа в строки и наоборот, когда такое преобразование имеет смысл. Например, если скрипт использует числа в контексте, где только строки имеют смысл, например, при соединении строк, он конвертирует числа в строки. Аналогичным образом, если требуется использовать строки там, где только числа имеют смысл, то Perl конвертирует их в числа. Работая со скриптами Perl, обычно не надо беспокоиться о внутреннем представлении скалярных величин.

Perl поддерживает также концепцию булевых значений, но не имеет для их описания специального типа. Как и в С, численное значение рассматривается истинным, если оно не равно нулю. Дополнительно строковое значение рассматривается как истинное, если оно не равно "" или "0". Некоторые булевы операторы,такие как <>> (больше), возвращают единицу в качестве значения<истинно> и нуль - в качестве <ложно>.

Тем самым, ваш скрипт должен просто рассматривать ненулевые величины как строчного типа,так и числового в качестве булева значения <истинно>. Скрипты Perl могут группировать скалярные величины вместе и создавать список (list). Если скрипт хранит список в какой-то переменной,то эта переменная становится массивом (array).

ПЕРЕМЕННЫЕ

Perl поддерживает три типа переменных: скаляры, массивы и ассоциативные массивы. Как и в языке С, имена переменных пишутся с различением строчных и заглавных букв. Таким образом, имена VAR, Var и var описывают различные переменные. Скрипт может иметь скалярную переменную под именем var и переменную-массив, также названную var. Они будут различаться в языке Perl в соответствии с контекстом.

Примечание: Переменные Perl нетипизированы, как это делается и в С. Например, скалярная переменная может содержать любой тип скаляра, и приведение типов осуществляется автоматически. Также, как вы могли уже заметить, переменные на языке Perl необязательно должны быть объявлены. Если переменная не объявлена, то Perl рассматривает ее как глобальную. Ниже вы познакомитесь с объявлением переменных и их областью видимости.

СКАЛЯРНЫЕ ПЕРЕМЕННЫЕ

Как отмечалось, скалярная переменная может содержать единственное значение. В языке Perl имена скалярных переменных всегда начинаются со знака ($). В следующем выражении скалярной переменной $age присваивается значение 35, а переменной $name строковое значение . Затем используется функция print для вывода значения каждой из переменных:

$age = 35; $name = "Bob"; print ($name,"is",$age);

Если вы сохраните эти выражения в файле под именем SCALAR.PL, то сможете запустить программу следующим образом:

C:\PERL> Perl SCALAR.PL Bob is 35

МАССИВЫ

Как было сказано выше, массивы представляют собой переменные, принимающие в качестве значения список из скалярных величин.Следующий текст программы на языке Perl иллюстрирует объявление переменных типа массив и их инициализацию:

@days = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat"); print(@days); # выведет "SunMonTueWedThuFriSat" print($days); # выведет "Thu" @weekdays = @days; # значение ("Mon","Tue","Wed","Thu","Fri") @emptylist = (); # постой список

Ссылка на переменные типа <массив> обычно начинается со знака (@) и сопровождается значениями в квадратных скобках ().Как и в программировании на языке С, индексами массивов для скриптов всегда являются переменные целого типа, которые обычно начинаются с нулевого значения. Вы увидите исключения из этих двух правил в примерах, которые будут объясненены в этой главе.Третье выражение ($days) служит примером массива, который ссылается на скалярное значение. Поскольку он содержит только один элемент, результирующее значение представляет собой скаляр.

Если использовать знак ($) вместо знака (@), то скрипт будет ссылаться на скалярную величину. Это замечание является очень важным. Квадратные скобки указывают, что скрипт ссылается на массив.Знак $, в свою очередь, означает ссылку на скалярную величину.Инициализация массива @weekdays осуществляется путем выборки части массива @days. В предыдущем примере массив @days использовался без индекса. Когда индекс опущен, Perl ссылается на весь массив. Аналогичным образом, в предыдущем примере массив @days инициализировался списком литералов.

Кроме того, что массиву могут присваиваться в качестве значений литералы, скрипт может также присваивать массивам значения переменных или даже других массивов, как показано ниже:

@stuff = ($age, $name) @FriendsOfMine = ("Joe","Mary", @FriendsOfYours);

В следующем примере используются части массивов:

@weekend = @days ; # результат ("Sun","Sat") print (@days); # выведет "MonTueWedThuFriSunSat"

Если скрипт использует переменную типа массив в контексте скаляра, то значением служит число элементов массива. Скалярным контекстом является такой контекст, где только скалярные значения имеют смысл. Например, следующее выражение использует скалярный контекст для массива stuff для того, чтобы определить число элементов содержащееся в массив. Если число элементов, больше или равно 2, то скрипт выдает сообщение и заканчивает исполнение:

(@stuff >= 2) || die "Too much stuff! \n";

Функция die служит директивой языку Perl закончить выполнение и выдать при этом указанное сообщение. Если сообщение не содержится, то функция просто заканчивает выполнение скрипта.

Perl также поддерживает специальную конструкцию $# переменная, которая возвращает последнее значение индекса в массиве. Например,следующее выражение for использует $[ для того, чтобы определить начальное значение индекса массива, и $# для определения последнего из элементов массива. При этом с помощью выражения for выводятся значения каждого из элементов:

For ($i =$[; $i <= $#stuff; $i++) { print $stuff[$i]; }

Записанный цикл for можно заменить следующим эквивалентным выражением:

Print @stuff;

РОЛЬ КОНТЕКСТА ДЛЯ ПЕРЕМЕННЫХ СКАЛЯРНОГО И ВЕКТОРНОГО ТИПА

Отметим, что оператор построения списка (,) выглядит точнотак же, как оператор (,) последовательного вычисления (sequentialevaluation). Какой из операторов используется, зависит от контекста, в котором он появляется, в частности, является ли переменная скаляром или массивом. Perl использует конструирование списков в контексте массивов и последовательное вычисление для скаляров. Рассмотрим следующие выражения:

@an_array = (1,2,3,4,5); $a_scalar = (1,2,3,4,5);

В первом выражении инициализируется массив, в то время как второе выражение устанавливает значение скалярной переменной $a_scalar равным 5, отбрасывая первые четыре величины. Рассмотрим два следующих выражения:

Print $assoc{1,2}; print @assoc{1,2};

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

@x = @list; $x = @list;

АССОЦИАТИВНЫЕ МАССИВЫ

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

$ages{"Bob"} = 35; $ages{"Mary"} = 25; $, = " "; # change output separator for print operator print @ages{"Bob","Mary"}; # выведет "25 35" print keys(%ages); # выведет "Bob Mary" for $name (keys(%ages)) { print "$name is $ages{$keys}\n"; }

Как можно видеть, программа присваивает значения переменной"$," (скалярная переменная, именем которой является запятая).Скрипт использует это выражение для того, чтобы при дальнейшем использовании оператора print выходные данные не сливались между собой. Далее в этой главе обсуждаются специальные переменные, такие как "$,". Ассоциативные массивы идентифицируются с помощью фигурных скобок. Так же как с массивами, при ссылках на ассоциативный массив целиком индексы не используются. Например, ссылка@ages{"Bob", "Mary"} использует индексы в скобках, что указывает на ассоциативный массив. Префикс @ указывает на то, что речь идето массиве. Аналогичное использование знака доллара перед массивом указывает, что используется скалярная величина.

Примечаиие: Если два ключа заданы, то вместе со знаком @ эта говорит о том, что речь идет о части ассоциативного массива и результат должен быть в виде списка. Такое выражение эквивалентно #ages{" Bob"}, #ages{"Mary"}. которое имеет своим значением величину (35, 25).

Выражение print keys(%ages) вызывает оператор keys, который возвращает полный список ключей ассоциативного массива. Ссылка %ages со знаком процента в качестве префикса означает, что ссылка относится ко всему ассоциативному массиву. Обратите внимание,что цикл for ссылается на переменные, заключенные в двойные кавычки. Наконец, последний из рассмотренных примеров также использует оператор keys и вводит цикл for для распечатки всех сочетаний ассоциативного массива. Цикл for ссылается на переменные,заключенные в двойные кавычки. Perl, в свою очередь, заменит значения, на которые ссылаются переменные, в то время, когда будет анализировать строку. Программисты называют этот процесс подстановкой переменной или интерполяцией.

Примечание: Perl не интерпретирует переменные, содержащие строки в одинарных кавычках.

ОПЕРАТОРЫ PERL

В то время как типы данных и переменных языка Perl значительно отличаются от соответствующих типов языка С, операторы ивыражения Perl должны вам показаться гораздо более знакомыми. Все операторы С присутствуют в языке Perl, за исключением оператора приведения типов (type), оператора обращения к содержимому указателя *ptr и оператора выбора члена структуры var.member илиvar->member. Кроме того, в языке Perl реализовано много новых операторов для использования в таких операциях как сравнение и обработка строк.

АРИФМЕТИЧЕСКИЕ ОПЕРАТОРЫ

Арифметические операторы действуют на числовые значения, и их результатом является число. Если выражение включает строковые операнды, то Perl конвертирует строковые значения в числовые перед тем, как оценить выражение. Perl выполняет преобразование строк в числа подобно тому, как это делает функция atof() языка С в библиотеки времени выполнения. В настоящее время Perl поддерживает следующие арифметические операторы:
- + сложение
- - вычитание или изменение знака
- * умножение
- / деление (только для чисел с плавающей запятой)
- % взятие по модулю (только для целочисленных значений)

Рассмотрим примеры следующих арифметических операций языка Perl:

$x = 2.5; $y = 3; print ($x + 2*$y); # выведет 8.5 print (7 / $y); # выведет 2.3333333 print int (7 / $y); # выведет 2 print (7 % $y); # выведет 1 print (7.5 % $y); # выведет 1

Примечание: В языке Perl оператор деления всегда имеет результатом число с плавающей точкой, а результатом взятия одного числа помодулю другого является целое число и причем предварительно оба операнда преобразуются к целому типу.

Рассмотрим следующую операцию взятия по модулю:

Print (7.9 % 3.6); # выведет 1 то же (7 % 3) = 1

Perl также поддерживает операторы инкремента и декремента:
- ++ декремент в префиксной или постфиксной форме
- - инкремент в префиксной или постфиксной формеРассмотрим примеры операций инкремента и декремента:

$x = 4; ++$x; print $x; # выведет 5 $y = $x-; # уменьшит x после присвоения y значения x print "$y $x" # выведет 5 4

Наконец, Perl обеспечивает арифметический оператор для возведения в степень (**). Рассмотрим следующие примеры использования операции возведения в степень:

$x = 2 ** 3; # результат 8 $x = 2 ** 0.5; # квадратный корень из 2 $x = -2 ** -3; # 1/(-2 в кубе), результат -1/8 (-0.125)

ПОБИТОВЫЕ ОПЕРАТОРЫ

Побитовые операторы воздействуют на бинарное представление целых чисел и имеют целочисленный результат. Если операндом является строка или дробное число, Perl предварительно преобразуетего в целое число, обрабатывает операнд, используя 32-битноепредставление. Все побитовые операторы С представлены в языкеPerl:
- | побитовое ИЛИ
- & побитовое И
- ^ побитовое исключающее ИЛИ
- ~ побитовая инверсия
- << сдвиг влево
- >> сдвиг вправо

Рассмотрим следующие примеры побитовых операций:

$x = 5; # 101 в двоичном $y = 3; # 011 в двоичном print $x | $y; # 7 (111) print $x & $y; # 1 (001) print $x ^ $y # 6 (110) print $x & ~1; # 4 (100) print $x << 2 # 20 (10100) print $x >> 1 # 2 (10)

Так же как в С, поведение операторов сдвига вправо зависит отреализации язы ка в случае, если операнд является отрицательным.

ОПЕРАТОРЫ СРАВНЕНИЯ

Операторы сравнения сравнивают величины двух операндов. Также как при работе с арифметическими операторами, Perl преобразует строчные операнды в численные перед тем, как выполнять сравнение. Для того чтобы позволить скрипту сравнивать строки, которые не являются числами, Perl имеет дополнительные операторы строкового сравнения. Эти операторы сравнивают строки, используявеличины ASCII. Если численное значение задано как операнд присравнении строк, оно сначала преобразуется в строку. Таблица 12.1перечисляет операторы сравнения:

Число Строка Значение = = eq равно!= nе не равно > gt больше чем < it меньше чем >= gе больше или равно <= lе меньше или равно <=> cmp не равно (результат со знаком)

Табл. 12.1. Операторы сравнения языка Perl.

Результатом операции сравнения является единица, если сравнение истинно и нуль в противном случае. Однако последняя операция (<=> или cmp) может возвращать значения -1, 0 или 1 в зависимости от того, является ли значение первого операнда меньше, чемвторого, равным ему или большим.

Примечание: Оператор cmp языка Perl ведет себя, аналогично функции Strcmp() библиотеки времени выполнения языка С.

Рассмотрим следующий пример сравнения:

$x = 5; # x равно 5 print ($x < 4); # если false, то выведет 0

ЛОГИЧЕСКИЕ ОПЕРАТОРЫ

Логические операторы анализируют булевы выражения и возвращают значения <истинно> или <ложно> в качестве результата. Perlобрабатывает операнды логических операций как булевы величины, т.е. как истинное или ложное значение.

Логические операторы языка Perl включают следующие:


- || логическое ИЛИ
- && логическое И

Perl всегда обрабатывает логические выражения слева направо. Кроме того. Perl всегда прекращает оценку, если уже выполненной оценки достаточно, чтобы определить значение результата. В дополнение к общим логическим операторам Perl поддерживает следующие дополнительные логические операторы:


- ! логическое отрицание ()
-
-: условная операция
- , последовательное выполнение

Оператор логического отрицания (!) заменяет значение булевой величины на противоположную. Так же как и в С, в языке Perl условный оператор (
-:) использует три операнда. Выражение, использующее условный оператор, имеет следующую форму:

Condition
- true-result: false-result

Аналогично, следующее выражение использует условный оператор для того, чтобы предоставить Бобу полный доступ, а всем остальным ограниченный:

$access = ($user eq "Bob"
- "Full" : "Limited");

Оператор последовательного выполнения <,> (также известный какоператор запятая) не является вполне логическим оператором, поскольку он не анализирует истинность своих операндов. Perl выполняет операнды оператора последовательного выполнения слева направо и возвращает значение самого правого операнда. Следующий пример иллюстрирует использование оператора запятая в цикле for.

For ($i=0, $j=10; $i<10; $i++, $j-) { print i$," ",$j }

СТРОКОВЫЕ ОПЕРАТОРЫ

Поскольку Perl представляет собой язык для обработки текста, неудивительно, что в него включены дополнительные операторы для работы со строками. Ниже перечисляются операторы обработки строк:
-. конкатенация строк
- х репликация
- =~ сопоставление переменной с образцом
- !~ то же, что и предыдущее, но с дополненным отрицанием результата

Первые два оператора легко иллюстрируются примером:

Print "b" . "an" x 2 . "a"; # выведет "banana"

Как показано, это выражение использует конкатенацию строк и оператор репликации для того, чтобы напечатать строку .Два последних оператора используются для проверки того, включает ли строковый операнд заданный образец. Этот вопрос детально обсуждается в разделе <Регулярные выражения>. Следующий пример иллюстрирует их использование:

$var = "banana"; print ($var =~ /ana/)
- TRUE: FALSE;

В этом случае оператор проверки вхождения в строку образца(=~) использовался для проверки того, входит ли образец ana в переменную $var. В данном случае выражение принимает значение <истинно>.

ОПЕРАТОРЫ ПРИСВАИВАНИЯ

Если вы знакомы с языком программирования С, то формы операторов присваивания языка Perl должны быть для вас совершенно знакомыми. Так же как и в С, эти операторы заставляют Perl выполнить специальные операции со значениями, которые появились с правой стороны оператора, и затем выполнить присваивание:

= += -= *= /= %= |= &= ^= ~= <<= >>= **= .= x=

LVALUES В языке Perl, так же как и в С, lvalue представляет собой имя того, что стоит с левой стороны оператора присваивания. Таким образом, lvalue представляет собой целостность, которой может быть присвоено значение, например, lvalue может быть переменной. Например, скрипт Perl не может присвоить значение строке символов, наподобие выражения = 32, поскольку не является lvalue. Тем не менее, скрипт может присвоить значение переменной $Bob, например, следующим образом $Bob = 32, посколькупеременная $Bob является lvalue. В языке Perl любая целостность,которая может использоваться как lvalue, обычно таковой и является. Например, следующее выражение упаковывает (pack) и распаковывает (unpack) список значений, причем список переменных в первом случае и три скалярных во втором являются lvalues:

@color = ($r, $g, $b); # пакет цветов ($r, $g, $b) = @color; # распаковка цвета

Когда вы работаете со списками в языке Perl, оператор присваивания не обязательно относится ко всему списку. Скрипт может присваивать значения отдельным элементам списка, как показано ниже:

@items = (100,200,300);

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

($arg1,$arg2,@rest) = @ARGV; # можно смешать скаляры и массивы

ОПЕРАЦИИ ДЛЯ РАБОТЫ СО СПИСКАМИ

В состав операций для работы со списками входят следующие:

Конструктор списков - .. оператор области - х оператор репликации

Вы уже использовали конструктор списков для инициализации массивов и создания списка переменных, использованных как lvalues. Оператор области возвращает в качестве значения последовательность целых чисел, которая начинается от левого операнда и продолжается до правого операнда включительно. Скрипты часто используют оператор области совместно с конструктором списков для создания списков. Например, следующее выражение использует оператор области для того, чтобы создать список под именем @digits,который содержит числа от нуля до девяти:

@digits = 0..9; # список (1,2,3,4,5,6,7,8,9)

Аналогичным образом, это выражение может использовать оператор области для создания области изменений индексов массива.Предположим, что список @days содержит дни недели (начиная с воскресенья). В следующем выражении списку @weekdays присваиваютсязначения, начиная от понедельника до пятницы:

@weekend = @days;

Наконец, следующее выражение использует два оператора области для создания списка шестнадцатиричных цифр:

@hex_digits = (0..9,a..f);

Оператор репликации просто создает копии данного операндауказанное число раз. Например, в следующем выражении список значений 1, 2, 3 повторяется три раза:

ОПЕРАТОРЫ ДЛЯ РАБОТЫ С ФАЙЛАМИ

Perl содержит обширный список операторов для работы с файлами. Имеется не менее 27 операторов, возвращающих специфическую информацию о файле, даже не открывая его. Многие операторы языка Perl ориентированы на системы UNIX, но следующие операторы работают на любых системах:

D проверяет наличие каталога
--е определяет наличие файла
--s определяет размер файла
--w определяет, можно ли писать в данный файл

Следующие два файловых оператора возвращают булево значение.Третий оператор возвращает размер файла в байтах. Следующий текст иллюстрирует использование этих операторов:

If (-e,"perl.exe") { print "File size is:" -s "perl.exe"; } else { print "can\" t find perl.exe\n"; } (-w "SomeFile") || die "Cannot write to SomeFile\n";

ПРИОРИТЕТЫ ВЫПОЛНЕНИЯ ОПЕРАТОРОВ

Как и всякий язык программирования, Perl определяет приоритеты выполнения операторов, с помощью которых упорядочиваетсяпоследовательность их выполнения. Таблица 12.2 перечисляет приоритеты операторов начиная от высшего и следуя к низшему:


- ++
- ! ~ унарный минус
- **
- =~ !~
- * / % х
- +
- <<>>
- -d -е -s -w (и другие файловые операторы)
- <> <= >= It gt le ge
- = = != < => eq ne cmp
- &
- |^
- &&
- ||
- ..
-
- : = += -= *=

Табл. 12.2. Приоритеты операторов языка Perl от высшего к низшему

В своем скрипте вы можете изменять последовательность выполнения операторов с помощью скобок.

КОНСТРУКЦИИ ЯЗЫКА PERL

Perl поддерживает все выражения языка С, используя почти идентичный их формат. Например, управляющие конструкции if,while, do. for и goto используются в обоих языках в одинаковой форме. Как вы увидите в дальнейшем, оператор continue имеет несколько иное значение в языке Perl. Его прежнее значение теперь называют next, а оператор break называют теперь last. Perl не реализует оператор switch. Кроме того, некоторые выражения языка С можно найти в Perl в иных форматах и добавлены многие новые выражения.

ПРОСТЫЕ И СОСТАВНЫЕ ОПЕРАТОРЫ

Простым выражением называется любая допустимая комбинация операторов и операндов. В языке Perl оператором является выражение, заканчивающееся точкой с запятой. Как и в языке программирования С, все операторы оканчиваются точкой с запятой. Когда вывводите текст программы в отладчик, можно опускать точку с запятой, поскольку отладчик поставит ее за вас. Следующий текст иллюстрирует простой оператор присваивания на языке Perl:

$Title = "Web Programming";

Так же как и при программировании на С, скрипты Perl могут содержать блоки операторов, или составные операторы, которые помещаются в фигурные скобки ({}), как показано ниже:

{ # Операторы # Другой блок операторов }

Ваши скрипты будут широко использовать блоки инструкций наряду с более сложными операторами. Как и в языке С, скрипты на языке Perl могут использовать блоки инструкций для определения области видимости (scope) локальных переменных. Однако определение локальных переменных в блоке не является автоматическим. Для их декларации скрипт должен использовать ключевое слово local.Далее в этой главе мы рассмотрим область видимости переменных в деталях.

УСЛОВНЫЕ ОПЕРАТОРЫ

Многие предыдущие примеры использовали оператор if. В языкеPerl оператор if почти что идентичен оператору if в языке С.Отличие, однако, состоит в том, что в языке С оператор if может использовать простую инструкцию без фигурных скобок, тогда как вязыке Perl инструкции обязательно должны быть заключены в фигурные скобки, образуя блок.

If (expr) statement; // приемлемо для C но не для Perl if (expr) { statement; # вот так нужно делать в Perl }

Аналогичным образом инструкции языка Perl else работает немного отлично от соответствующей инструкции в С. В языке Perl инструкции также должны быть заключены в фигурные скобки и образовать блок:

// Пример в С неприемлемо в Perl if (expr1) statament1; else if (expr2) statement2; else ststement3;

Ниже показано, что Perl позволяет использовать конструкциюelsif:

If (expr1) { statament1; } elsif (expr2) { statement2; } else { ststement3; }

ОПЕРАТОР UNLESS

В языке программирования С программисты используют логическое отрицание (!) для изменения булевой величины на противоположное, как показано ниже:

If (!(expr)) // Отрицание на С { statement; }

Наряду с использованием логического отрицания, скрипты Perlчасто содержат оператор unless, который обеспечивает то же самое,что и записанный выше код на С.

Unless (expr) { statement; }

Примечание: В отличие от языка С, Perl не содержит оператора переключения switch.

ОПЕРАТОР DO

Одним из частных случаев блочных операторов служит операторdo, который позволяет блоку инструкций возвращать значения. Значением, которое оператор do возвращает, является значение последнего выражения, оцененного в рамках блока. Например, следующий оператор do сравнивает строковую переменную $Month с месяцами года и присваивает переменной $DayCount значение, равное числу днейв месяце:

$DayCount = do { if ($Month eq "September" || $Month eq "April" || $Month eq "June" || $Month eq "November") { 30; } elsif ($Month eq "Februry") { $Year & 3
- 28: 29; # Проверка на весокосный год } else { 31; } };

Обратите внимание, что Perl требует наличия точки с запятойв конце блока do. Не путайте блок do с оператором do while, который будет рассматриваться ниже в этой главе.

ЦИКЛЫ И ВЕТВЛЕНИЯ

Perl поддерживает операторы циклов for, while и do с небольшими отличиями от их реализации в языке С. Существенным отличием служит то, что Perl требует использования инструкций блоками, заключенными в фигурные скобки. Кроме того, как вы познакомитесь, далее, Perl расширяет конструкцию цикла, что6ы обеспечитьее некоторые новые формы. В следующих примерах циклы for, while иdo работают аналогичным образом на языках С и Perl:

For($i = 0; $i< 100;$i++) { printf("%d\n", $i) ; } while ($i > 0) { printf("%d\n", $i-); } do { printf("%d\n", $i++); } while ($i < 0);

Конструкция циклов на языке С отлична от конструкции на языке Perl еще и в том, что Perl не содержит оператора break, а оператор continue выполняет совершенно иную функцию. К счастью, Perlобеспечивает некоторые новые, более гибкие и более интуитивно понятные конструкции:


- last выход из цикла (как оператор С break)
- next начать новую итерацию (как оператор С continue)
- redo повторить текущую итерацию

Для понимания конструкций циклов на языке Perl, необходимо разобраться с использованием блока continue. Рассмотрим следующий цикл while, который содержит блок continue:

$i = 100; while ($i > 0) { print $i; } continue {$i-}

Вы можете представлять себе блок continue как третье выражение в цикле for, которое выполняется на каждой итерации. Аналогичным образом Perl выполняет блок continue в конце каждой итерации. Однако, как вы узнаете далее, блок continue обеспечивает скрипту более полный контроль над процессом, чем обеспечиваетцикл for. Когда цикл на языке Perl использует оператор next, блокcontinue все равно выполняется, если только он существует. Однако если цикл использует оператор redo, блок continue не исполняется.

МЕТКИ

В скрипте Perl метки просто означают имя, соответствующеенекоему положению внутри скрипта. Имена меток оканчиваются двоеточием (например, outerloop:). Используя оператор goto, скрипт может осуществлять переходы на метку. Дополнительно могут использоваться операторы last, next и redo, для перехода к метке.Следующий код иллюстрирует использование оператора last для перехода на метку:

Outerloop: while ($i > 0) { while ($j > 0) { #Здесь какой-нибудь другой процесс if ($needToAboutLoop) { last outerloop; } } }

В этом случае инструкция содержит ветвь last для перехода наметку outerloop и окончания выполнения цикла.

ЦИКЛ UNTIL

Еще одной конструкцией цикла в языке Perl является циклuntil, который является противоположностью циклу while. Как выпомните, в цикле while инструкции выполняются до тех пор, пока выполняется заданное условие. В цикле until, напротив, инструкции выполняются до тех пор, пока не будет выполнено условие. Например, рассмотрим цикл while, такой, как показан на следующейстранице.

While (!(expr)) { statement; }

Используя цикл until, можно создать идентичный цикл, показанный ниже:

Until (expr) { statement; }

Аналогичным образом следующая конструкция do while использует оператор логического отрицания для того, чтобы выполнять цикл, пока заданное булево выражение не станет истинным:

Do { statement; } while (!(expr));

Используя конструкцию do until, вы можете сформировать идентичный цикл без использования логического отрицания:

Do { statement; } until (expr);

ЦИКЛЫ FOR И FOREACH

Perl поддерживает цикл for совершенно аналогично языку С:

For (statement1; expression; statement2) { statement3; }

Например, следующий код использует цикл for для того, чтобывывести значения чисел от 0 до 100:

For ($digit = 0; $digit <=100; $digit++) { print $digit, " "; }

Дополнительно Perl содержит конструкцию цикла foreach, который позволяет скрипту организовывать итерации в списках и массивах. Рассмотрим пример:

@list = ("a","b","c"); foreach $arg (@list) { print "List item: $arg\n"; } foreach $i (1..10) { print "iteration $i\n" }

В первом случае цикл foreach осуществлял перебор значений всписочной переменной @list. Во втором примере в цикле foreachосуществляется перебор чисел в диапазоне от 1 до 10. Внутри цикла foreach может фигурировать список, состоящий из литералов, или массив, как было проиллюстрировано в предыдущем примере. После выполнения одной итерации циклом, специальная скалярная переменная {$arg в первом случае и $i во втором случае) принимает значение из заданного списка элементов. Область видимости этой скалярной переменной в цикле foreach ограничивается телом цикла. Поэтому скалярная переменная цикла, foreach не будет конфликтовать с идентичным именем переменной, определеннойвне цикла. В следующем коде переменная с именем $i используется внутри и вне цикла foreach:

$i = 1001; foreach $i (1..9) { print "$i\n"; # цикл выведет 123456789 } print "$i\n";

Как можно увидеть из этого примера, переменная $i, используемая для организации итераций цикла, не конфликтует с переменной $i, определенной вне цикла. Особенностью цикла, foreach, которую ваши скрипты могут использовать, является возможность модификации элементов массива.(Будьте осторожны при реализации этой возможности!) Рассмотрим следующий цикл foreach, который добавляет значение 10 каждому элементу массива:

@list = 1..5; foreach $i (@list) { $i += 10; } $, = " "; print @list; # выведет 11 12 13 14 15

Сделаем несколько заключительных замечаний относительно цикла foreach. В языке Perl имена foreach и for рассматриваются как синонимы. Поэтому в скриптах можно использовать эти имена попеременно. Perl, в свою очередь, будет определять тип цикла, основываясь на его контексте.

ОПЕРАТОР БЕЗУСЛОВНОГО ПЕРЕХОДА GOTO

Perl поддерживает оператор безусловного перехода goto, который является идентичным такому же оператору языка программирования С. Ниже приведен пример использования оператора goto для вывода чисел от 1 до 10:

$i = 1; loop: print $i++, " "; if ($i <=10) { goto loop; }

МОДИФИКАТОРЫ ОПЕРАТОРОВ

В языке Perl используются специальные формы конструкции if,unless, while и until, которые позволяют управлять ходом вычислений. В определенных случаях эти cпециальные конструкции могут сделать ваш код более ясным и легко читаемым. Для того, чтобы кодбыло легче читать и его смысл был более очевиден, целесообразно выбирать подходящий формат для записи. Рассмотрим следящее выражение, использующее функцию die для того, чтобы закончить выполнение скрипта, если значение переменной $count меньше чем 10:

If ($count < 10) { die; }

Если расположить функцию die перед оператором if, как показано ниже, число строк кода уменьшится:

Die if ($count < 10);

Аналогичным образом, то же самое выражение может быть записано в следующем виде:

($count >= 10) || die;

В данном случае, если переменная $count больше либо равна10, Perl прекращает дальнейшее вычисление в данной строке и функция die не выполняется В противном случае, если переменная $count меньше 10, после вычисления первой части выражения код запускает функцию die и тем самым заканчивает выполнение скрипта. Наконец, в следующем примере использование конструкции unless также позволяет уменьшить число строк до одной:

Die unless ($count >= 10);

Аналогичным образом, следующие циклы while являются идентичными:

$i = 0; while ($i < 10) { $i++; } $i = 0; $i++ while ($i < 10);

Как можно видеть, используя модификацию конструкции, скриптпозволяет сократить число строк в записи цикла до одной. Аналогичным образом, следующие циклы until эквивалентны:

$i = 10; until ($i >= 10) { $i++; }; $i = 10; $i++ until ($i >=10);

Примечание: Во всех четырех случаях, даже если выражение для оценивания расположено после инструкции для выполнения, Perl сначала анализирует условие и только потом выполняет инструкцию.

ГЕНЕРАЦИЯ ДИНАМИЧЕСКИХ ВЫРАЖЕНИЙ С ПОМОЩЬЮ ФУНКЦИИ EVAL

Поскольку Perl является интерпретируемым языком, ваши скрипты могут использовать Perl для того, чтобы генерировать код <налету>, то есть динамически, во время исполнения скрипта. Именнотак работает отладчик Perl (который сам является Perl-программойс именем Perldb.PL). Проектируя скрипты, вы можете использоватьтакой динамический код для создания динамических переменных именили даже построения специальных подпрограмм. Perl оценивает динамические выражения, используя функцию eval. В следующем примересоздается динамическая инструкция путем присвоения переменной в качестве значения текста, который, собственно, и содержит требуемую инструкцию языка Perl. Дальнейшие инструкции используют функцию eval для того, чтобы выполнить эту инструкцию:

$perl_statement = "print "Hello, world\n";"; eval $perl_statement; # выведет Hello, world $i = 1001; $varname = "$i"; print eval $varname; # выведет значение $i

Примечание: Использование скриптом функции eval таит в себе опасности, в особенности, если скрипт передает функции eval данные, полученные от пользователя. Используя функцию eval, скрипт может выполнить произвольную команду языка Perl, включая даже системные команды. Это дает возможность пользователю контролировать программу, что может быть особенно рискованным для сетей Internet и Web.

ПОДПРОГРАММЫ

Как и все структурированные языки программирования, Perl поддерживает подпрограммы. Подпрограмма может быть определена спомощью ключевого слова sub, как показано ниже:

Sub demo_sub { print "demo_sub called\n"; } &demo_sub; # вызов подпрограммы

В данном случае инструкции образуют подпрограмму, названную demo_sub. Для вызова подпрограммы скрипт помещает знак амперсанда (&) перед именем подпрограммы. При вызове подпрограммы в языке Perl скобки могут быть опущены. Вы можете разместить подпрограмму где угодно в пределах исходного кода скрипта, потому что Perl проанализирует весь исходный текст перед тем, как начать выполнение скрипта. Можно объявить подпрограмму в исходном коде сразу после первого использования подпрограммы (forward reference). Подпрограммы могут иметьаргументы и возвращать значения. Следующий фрагмент кода содержит подпрограмму с именем show_value, которая выводит значение, полученное подпрограммой в качестве параметра:

Sub show_value { print "The value id ", $_; } &show_value(1001);

Формально подпрограмма языка Perl не объявляет переменныхдля хранения аргументов. Вместо этого в подпрограмму передается переменная типа массив с именем @_, которая содержит значения параметров. В свою очередь, подпрограмма получает доступ к значениям аргументов, используя следующие обозначения для элементов массива: $_, $_, и т. д. Однако такой способ передачи параметров может ухудшать читаемость кода, и поэтому большинство подпрограмм используют копирование аргументов в локальные переменные. Аналогично предыдущему примеру, следующая подпрограмма show_fwo_values выводит значения двух параметров:

Sub show_two_values { print "Первый параметр ", $_, "\n"; print "Второй параметр ", $_, "\n"; } &show_two_values(1001, 2002);

Наконец, следующая функция show_all_values выводит значения всех параметров, которые она получает. Функция использует массивдля определения числа параметром:

Sub show_all_values { for ($i = 0; $i < @_; $i++) { print "Parametr ", $i, " is ", $_[$i], "\n"; } } & show_all_values(1001,2002,3003,4004);

Как было сказано, подпрограммы Perl могут возвращать значения. Для этого используется инструкция return. В противоположность языку С, Perl не требует обязательного использования инструкции return. Если подпрограмма не содержит инструкцию return,то в качестве возвращаемого значения будет взято последнее оцененное выражение. В следующем примере складываются два параметраи возвращается результат:

Sub add_values { return $_ + $_; } print "The result is: ", &add_values(1001,2002);

БИБЛИОТЕКА ПОДПРОГРАММ

В противоположность языку С, Perl фактически не поддерживает концепцию библиотеки. Тем не менее, в нем имеется механизм,позволяющий скриптам использовать исходный код из другого файла.Например, предположим, что вы храните подпрограмму add_valuesl вфайле под именем addvalue.pl. Используя инструкцию require, другой скрипт на языке Perl может получить доступ к той подпрограмме, как показано ниже:

Require "addvalue.pl"; print &add_values(10,11);

Вы можете представлять себе инструкцию require как аналогоператора #include препроцессора языка С. Чтобы найти файл исходных кодов, Perl сначала ищет в каталоге, определенном по умолчанию для библиотеки языка Perl (подробности можно уточнить в инструкции по инсталляции), а затем в текущем каталоге. Можно также использовать абсолютный или относительный путь, к которому добавлено имя файла. Perl запоминает, какие файлы были затребованы оператором require, и загружает их только один раз даже в случае многочисленных обращений к этим файлам. Имеется много стандартных библиотек, которые расширяют возможности языка Perl. Сейчас самое время побродить по каталогу, в котором хранятся библиотечные файлыязыка Perl, чтобы получить представление о тех возможностях, которые они предлагают.

ИСПОЛЬЗОВАНИЕ ПАКЕТОВ ДЛЯ ИЗОЛЯЦИИ ПОДПРОГРАММ

Если у вас имеется много подпрограмм, особенно подпрограмм,которые вы храните в различных файлах, то может возникнуть коллизия имен переменных, когда одно и то же имя переменной используется в различных целях. Perl помогает избежать этого с помощью пакетов (packages). Как известно, объявляя локальные переменные для подпрограмм, можно избежать коллизии имен. Однако если несколько подпрограмм совместно используют какие-то специфические данные, то эти данные могут потребовать глобальной области видимости, что как раз и может вести к коллизии имен.Используя пакеты, можно группировать глобальные данные в частные пространства имен (name-spaces), вне пределов которых глобальные переменные не видны, т. е. неизвестны. Рассмотрим приведенный ниже простой пример, в котором две подпрограммы (находящиеся в различных файлах) используют частные, индивидуальные пространстваимен.

# Код в файле one.pl sub sub_one { package demo_one; $some_data = 10; } # * * * * * * * * # Код в файле two.pl sub sub_one { package demo_two; $some_data = 20; }

Как можно видеть, первая подпрограмма использует имя пакетаdemo_one, вторая подпрограмма использует имя пакета demo_two. Обе подпрограммы могут устанавливать и использовать переменную $some_data без возникновения коллизии имен между одной и другой глобальными переменными. Скрипт <знает> имя пакета, в пределах которого находится переменная, и он организует доступ к ней, использует имя пакета вкачестве префикса к имени переменной. В следующем примере имя пакета package_one или package_two добавляется в качестве префиксак имени переменной some_data:

&sub_one; &sub_two; print "Переменная 1 $package_one"some_data\n" print "Переменная 2 $package_two"some_data\n"

Когда вы используете пакеты языка Perl, можете создать уникальное пространство имен в пределах текущего файла исходных кодов путем помещения инструкции package в начале файла, как показано ниже:

Package some_package_name $some_data = 1; sub some_sub { return $some_data; }

В данном случае переменная $some_data существует только в пакете и поэтому защищена от некорректного доступа. Использование пакета, таким образом, обеспечивает данным ту же область видимости, что и в языке программирования С, где глобальные переменные имеют своей областью видимости тот файл исходных кодов, вкотором они объявлены. При вызове подпрограммы из другого файла скриптов необходимо использовать имя пакета:

Require "some_package.pl"; print &some_package_name"some_sub;

ОБРАБОТКА СТРОК

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

ФУНКЦИЯ CHOP

Функция chop удаляет последний символ строки. Она имеет следующий формат:

$character = chop(Str);

Функция chop возвращает удаленный символ. Скрипты языка Perlшироко используют chop для удаления символа перехода на новуюстроку и символа конца строки.

ФУНКЦИЯ INDEX

Функция index осуществляет поиск заданной подстроки в строке. Она имеет следующий формат:

$location = index(Str, SubStr[, Offset]);

Функция index возвращает индекс первого вхождения подстроки(SubStr) в строку (Str). Факультативно может быть задан сдвиг отначала (Offset), после которого начинается поиск. Если подстрокане найдена, возвращается значение -1. В следующем примере функция index ищет вхождения подстроки "па" после третьего символа встроке "banana":

Print index("banana","na",3); # Выведет 4.

ФУНКЦИЯ RINDEX

Функция rindex ищет последнее, самое правое вхождение подстроки в строку и возвращает значение позиции первого символа подстроки. Функция имеет следующий формат:

$location = rindex(Str, SubStr);

Эта функция аналогична функции index, за исключением того,что она возвращает последнее вхождение, а не первое. Например, в следующем примере функция rindex используется для определения последнего вхождения подстроки "na" в строку "banana":

Print rindex("banana","na"); # Выведет 4

ФУНКЦИЯ LENGTH

Функция length возвращает число символов в строке. Она имеетследующий формат:

$len = length(Str);

В следующем примере функция length используется для выводачисла символов в строке:

Print length("banana"); # Выведет 6

ФУНКЦИЯ SUBSTR

Функция substr используется для удаления части строки. Онаимеет следующий формат:

$substring = substr(Str, Offset[,Len]);

Функция возвращает подстроку, т. е. часть строки, длина которой не превышает величины, заданной факультативным параметром Len. Возвращаемая подстрока строки str начинается с символа в позиции, заданной сдвигом Offset. Если параметр Len опущен, то возвращаемая строка содержит символы до конца строки включительно.Если параметр Offset отрицательный, то сдвиг вычисляется от конца строки. Наконец, скрипт может использовать substr как lvalueдля выполнения операции присваивания. Следующий фрагмент кода иллюстрирует использование функции substr.

Print substr("orange",3); #Выведет "nge" print substr("orange",-2); # Выведет "ge" print substr("orange",2,2); # Выведет "an" $str = "apple"; substr($str,-3) = "ricot"; print $str; # Выведет "apricot"

Примечание: Часто использование операторов языка Perl для регулярных выражений оказывается более эффективным, чем функции substr. Регулярные выражения обсуждаются ниже в данной главе.

ФУНКЦИЯ JOIN

Функция join соединяет список элементов в строку, разделяя каждый элемент заданным символом. Она имеет следующий формат:

$new_string = join(Str,List);

Функция join конвертирует каждый элемент списка в строку исоединяет строки. Следующий фрагмент кода иллюстрирует использование функции join:

$str = join(",", 0..4,10,20); # Список будет "0,1,2,3,4,10,20" $strn = join ("\t", $a, $b, $c);# Смешает списки

ФУНКЦИЯ SPLIT

Функция split разделяет содержимое строки на список элементов. Она имеет следующий формат:

Split(Delimeter, Str[,Limit]);

Аргумент Delimeter определяет символ, по которому осуществляется разделение, например, пробел, слово, символ табуляции ит. д. Факультативный параметр Limit задает максимальное число элементов, которое может содержать список. Следующий пример иллюстрирует использование функции split.

ФУНКЦИИ ДЛЯ ОБРАБОТКИ СПИСКОВ

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

ФУНКЦИЯ REVERSE

Функция reverse реверсирует элементы списка. Она имеет следующий формат:

@new_list = reverse(@List);

Функция reverse реверсирует список и возвращает новый результирующий список. Следующий пример иллюстрирует использование функции reverse:

@list = reverse(1..5); # Результат 5,4,3,2,1 @list = reverse(@list); # Результат 1,2,3,4,5

ФУНКЦИЯ SORT

Функция sort сортирует элементы списка. Она имеет следующийформат:

@new_list = sort(@List);

@new_list = sort(Subroutine @List);

@new_list = sort(BlockStatement @List);

Функция sort размещает элементы в списке, упорядочивая их всоответствии с порядковыми номерами символов в таблице ASCII-кодов. Так же как и функция reverse, функция sort возвращает в качестве значения новый список и не воздействует на исходный список. Следующий пример иллюстрирует использование функции sort:

@list = sort (1,5,2,3,4); # Результат 1,2,3,4,5 @list = sort(1,2,10); # 1,10,2 сортировка в ASCII

В подпрограмме или блоке можно изменять упорядочение, всоответствии с которым выполняется сортировка. Следующий примериллюстрирует использование функции sort.

@list = sort({$a <=> $b} (2,1,10)); # @list 1,2,10 @list = sort({$b <=> $a}) (2,1,10); # @list 10,2,1 sub mycomp { $b <=> $a } @list = sort(mycomp (2,1,10)); # @list 10,2,1

ФУНКЦИИ РАБОТЫ С МАССИВАМИ

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

ФУНКЦИИ PUSH И POP

Скрипты языка Perl используют фикции push и pop для того,чтобы добавлять и удалять элементы с конца массива. Иными словами, функции push и pop позволяют скриптам выполнять операции состеком по принципу: последним вошел, первым вышел. Функция push имеет следующий формат:

Push(@ARRAY, LIST);

Следующий фрагмент иллюстрирует использование функции push:

@list = (); push(@list,10,20); # @list теперь (10,20) push(@list,1..3); # @list теперь (10,20,1,2,3)

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

$value = pop(@ARRAY);

Следующий фрагмент программы иллюстрирует использование функции pop:

# Возьмём @list из предыдущего примера print pop(@list); # Выведет 3 print pop(@list); # Выведет 2 # Теперь @list (10,20)

ФУНКЦИЯ SHIFT

Функция shift удаляет и возвращает элемент из начала массива. Эта функция аналогична функции pop с тем только отличием, чтоработает от начала массива по принципу FIFO (<первым вошел, первым вышел>). Функция shift имеет следующий формат:

$value = shift(@ARRAY);

Следующий фрагмент программы иллюстрирует использование функции shift:

# Возьмём @list из предыдущего примера

Print shift(@list); # Выведет 10 print shift(@list); # Выведет 20 # Теперь @list ()

ФУНКЦИЯ UNSHIFT

Функция unshift добавляет один или больше элементов к началу массива. Она имеет следующий код:

Unshift(@Array, List);

Следующий фрагмент программы иллюстрирует использование функции unshift:

# @list = () unshift(@list,5,10,20); # @list (5,10,20) unshift(@list, 1..3); # @list (1,2,3,5,10,20)

ФУНКЦИЯ SPLICE

Скрипты языка Perl используют функцию splice для того, чтобы извлекать элементы из списка, заменяя их элементами другого списка. Она имеет следующий формат:

Splice(@Array, Offset[, Count[, List]]);

Функция splice извлекает указанное число элементов {Count)из массива (@Аrraу), начиная с элемента, на который указывает величина сдвига (Offset), и заменяет элементы элементами другого списка (List). Если в вызове функции не указан параметр Count, функция извлекает элементы до самого конца массива. Если в вызове функции не указан список, элементами которого замещаются исходные элементы, то функция не добавляет никаких элементов к первоначальному списку. Следующее выражение иллюстрирует использование функции splice:

@list = 1..10; splice(@list,1,8,5,6); # @list = (1,5,6,10)

ФУНКЦИЯ SCALAR

Функция scalar определяет число элементов в списке. Онаимеет следующий формат:

Rsult = scalar(List);

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

@list = 1..10; print scalar(@list); # Выведет размер @list

ФУНКЦИЯ GREP

Функция grep фильтрует элементы списка, для которых заданное выражение принимает значение <ложно>. Она имеет следующий формат:

@list = grep(Expression, List);

Функция grep просматривает элементы списка, подставляя их вкачестве аргумента в заданное выражение. Функция grep присваивает текущее выражение элемента списка переменной $_ и вычисляет заданное выражение. Если полученное выражение является истинным,то функция grep добавляет этот элемент к результирующему списку.Следующий фрагмент программы иллюстрирует использование функции grep:

@list = grep($_ & 1, 1..10); # @list (1,3,5,7,9) @list = ("a", "" "b"); # @list ("a"," ","b") @list = grep($_ eq "", @list); # @list ("a","b")

Примечание: Если выражение, модифицирует переменную. $_, то исходный список также будет модифицирован.

ФУНКЦИИ ОБРАБОТКИ АССОЦИАТИВНЫХ МАССИВОВ

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

ФУНКЦИЯ KEYS

Функция keys возвращает значения ключей, которые отвечаютассоциативному массиву. Она имеет следующий формат:

@key_list = keys(%Array);

Функция keys возвращает массив ключей в виде регулярного списка. Следующий фрагмент программы иллюстрирует использование функции keys:

$ages{"Bob"} = 25; $ages{"Mary"} = 30; $ages{"Zack"} = 15; @list = keys(%ages); # @list будет "Zack", "Bob", "Mary" @list = sort keys %ages # @ list "Bob", "Mary", "Zack" for $key (sort keys %ages) { print "$key is $ages{$key}\n" }

ФУНКЦИЯ VALUES

Функция values возвращает обычный массив, состоящий из значений ассоциативного массива. Она имеет следующий формат:

@value_list = values(%Array)

Функция values возвращает массив значений ассоциативного массива в виде регулярного списка. Следующий фрагмент программы иллюстрирует использование функции values:

# Используем значения из предыдущего примера %ages = ("Bob", 25, "Mary", 30, "Zack", 15); @list = sort values %ages; # @list (15, 25, 30) @list = %ages; # @list ("Zack", 15, "Bob", 25, "Mary", 30)

ФУНКЦИЯ EACH

Функция each осуществляет итерации элементов в ассоциативном массиве. Она имеет следующий формат:

@key_values = each(%Array);

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

# Используем значения из предыдущего примера %ages = ("Bob", 25, "Mary", 30, "Zack", 15); while (($name, $age) = each %ages) { # Выведем ages print "$key is $ages{$key}\n"; }

ФУНКЦИЯ DELETE

Функция delete удаляет элементы ассоциативного массива. Онаимеет следующий формат:

Delete $Array{Key}

Следующая инструкция использует функцию delete для того,чтобы удалить элемент, отвечающий ключу Bob из ассоциативного массива $Employees:

Delete $Employees{"Bob"}

АРГУМЕНТЫ КОМАНДНОЙ СТРОКИ

Скриптам на языке Perl легко получить доступ к аргументам командной строки. Всякий раз, когда запускается скрипт, Perl помещает аргументы командной строки скрипта в списочную переменную @ARGV. Следующий фрагмент программы служит для вывода аргументов командной строки на дисплей:

While ($arg = shift @ARGV) { print "$arg\n"; }

ДОСТУП К ПЕРЕМЕННЫМ ОКРУЖЕНИЯ

Доступ к переменным окружения осуществляется в скриптах наязыке Perl также очень просто. Всякий раз при запуске скриптаPerl помещает копии переменных окружения в ассоциативный массив сименем %ENV. В следующей инструкции массив %ENV используется для вывода текущего каталога:

Print "$ENV{PATH}\n"; # Выведет текущий каталог

Кроме получения значений из массива %ENV, скрипты также могут изменять элементы массива. Такие изменения массива %ENV изменят установку переменных окружения для всякого процесса-потомка,создаваемого скриптом. Например, следующая инструкция используетмассив %ENV для изменения текущего пути:

$ENV{PATH} = "c:\\myexec;".$ENV{PATH};

Примечание: Изменения, которые скрипт делает в массиве %ENV, неповлияют на исходные переменные окружения. Иными словами, после окончания работы скрипта переменные окружения системы не изменятся.

ФАЙЛОВЫЙ ВВОД И ВЫВОД

Perl специально разрабатывался для того, чтобы служить адекватным средством для чтения и записи в текстовые файлы. Тем не менее, как вы узнаете далее, Perl выполняет функции по произвольному доступу и вводу-выводу бинарных файлов. Операции по работе с файлами требуют указатель файла (file handle), который является переменной, соответствующей конкретному файлу. По умолчанию каждый скрипт на языке Perl имеет три стандартных указателя,которые Perl автоматически открывает при запуске скрипта: STDIN,STDOUT, STDERR. Эти три стандартных указателя отвечают стандартным потокам STDIN, STDOUT, STDERR языка программирования С. Кроме того, скрипт языка Perl может открыть дополнительные указатели для других специфических файлов.

ОТКРЫТИЕ ФАЙЛОВ И ДРУГИХ ПОТОКОВ

Для того чтобы скрипт использовал файл, он должен вызвать функцию open. Она имеет следующий вид:

Open(FileHandle[, FileName])

В отличие от функции open библиотеки времени выполнения языка С, функция open языка Perl не содержит параметра mode в вызове функции. Perl определяет режим (mode) открытия файла, основываясь на имени файла. Таблица 12.3 иллюстрирует связь режима открытия файла и имени файла.

Табл. 12.3. Соглашение об именах и режимах доступа файлов языка Perl


-Примечание: Режим канального (pipe) потока может существовать не на всех системах.

Если в вызове функции open опущено имя файла, то Perl подразумевает, что имя файла содержится в строковой переменной $FileHandle. Когда скрипт завершил использование файла, он закрывает его, используя функцию close, как показано ниже:

Close(FileHandle);

фрагмент программы иллюстрирует использование функций open и close:

Open(InFile, "test.dat") || die; # открываем для чтения # test.dat open(OutFile, ">test.dat") || die; # создаём test.dat $AuxFile = ">>test.dat"; open(Aux, $AuxFile) || die; # открывает для дополнения # test.dat close(InFile); close(OutFile); close(Aux);

Обратите внимание, что указатели файлов не имеют обычных односимвольных префиксов. Как вы узнаете далее, скрипты языка Perl могут хранить имена указателей в виде строк скалярных переменныхи передавать указатель любой функции, которая может их обрабатывать. При необходимости Perl выполняет конвертацию значений.

В операционной системе MS-DOS Perl поддерживает дополнительную функцию, которая называется hinmode и позволяет файловому вводу/выводу переключаться между текстовым и бинарным режимами. В большинстве же систем различие между текстовым и бинарным режимами не имеет значения. Однако для операционной системы MS-DOS символ новой строки представляет собой последовательность из двух символов (CR+LF). Поскольку большинство программ не ожидают встретить два символа в конце строки, то система ввода/вывода должна выполнить преобразование. Для того чтобы можно было использовать функцию binmode, соответствующий указатель может быть открыт. Функция binmode имеет следующий формат:

Binmode(FileHandle);

ПОСТРОЧНОЕ ЧТЕНИЕ И ЗАПИСЬ ДАННЫХ

Простейшим способом для чтения скриптом строки из файла служит использование оператора . В языке Perl указатель файла, окруженный треугольными скобками, становится символом ввода (input-symbol). Например, следующий фрагмент программы иллюстрирует использование символа ввода для чтения и вывода на экран содержимого файла Test.dat.

Open(InFile, "Test.dat") || die; while ($line = ) { print $line; # Выведет строку из файла } close(InFile);

Когда символ ввода достигает конца файла, он возвращает значение false, которое в данном случае заканчивает выполнение цикла while. Существует специальный (пустой) символ ввода, обозначаемый <>, который имеет весьма специальное, но полезное применение. В первый раз, когда скрипт использует пустой символ ввода<>, он анализирует аргументы командной строки. Если строка @ARGV является пустой, то входной символ <> читает из STDIN. Если вместо того @ARGV не пуста, то Perl открывает первый из файлов, указанных в переменной @ARGV, и читает содержимое файла. Когда Perlзаканчивает обработку одного файла, он приступает к следующему.После того как скрипт прочитал все файлы, символ <> возвращает значение false. Скрипты языка Perl также могут использовать символ ввода для чтения всего содержимого файла в массив так, что каждая строка файла становится элементом массива. Например, следующая инструкция читает из файла STDIN в массив @lines:

@lines = ;

Запись данных в файл также достаточно проста. Фактически вы это делали всякий раз, когда использовали функцию print. Полный формат функции print имеет следующий вид:

Print List;

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

Open(LogFile, ">>logfile.dat") || die; ############## ($m, $d, $y) = (localtime(time)) ; print LogFile "Captain"s log, Stardate ++m$/$d/$y\n"; close(LogFile);

Примечание: Указатель файла и выходной список не разделяются запятой.

ЧТЕНИЕ И ЗАПИСЬ БЛОКОВ ДАННЫХ

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

$result = sysread(FileHandle, $Var, Length[, Offset]); $result = syswrite(FileHandle, $Var, Length[, Offset]);

Если в вызове функций указывается сдвиг от начала файла(Offset), то функции выполнят поиск места, с которого они начнутоперации ввода/вывода. Функции sysread и syswrite обе передаютданные, используя скалярную переменную строкового типа. Поскольку функции обрабатывают фиксированные блоки памяти, то данные могут содержать бинарные значения, включая нули и маркерыконца файла. Если в вызове функции указывается сдвиг от началафайла (Offset), то функция выполняет поиск места в файле, с которого начинает выполнять операции ввода/вывода. Если вы работаете с блоками данных, то скрипты могут также использовать следующие функции ввода/вывода:

$result = seek(FileHandle, Position, Base); $result = tell(FileHandle); $result = eof(FileHandle);

Функция seek работает в точности так же, как fseek - функция библиотеки времени выполнения языка С. Параметр Position задает позицию относительно начала отсчета, которая в свою очередьзадается параметром Base следующим образом:


- 0 Поиск от начала файлов
- 1 Поиск от текущей позиции
- 2 Поиск от конца файла

Функция tell языка Perl работает в точности так же, как фикция ftell библиотеки времени выполнения языка С. Эта функция возвращает текущую позицию в файле, с которой выполняются операциичтения или записи. Наконец, функция eof, так же как и функцияfeof языка С, возвращает значение <истинно> или <ложино>, которое скрипт может использовать для определения достижения концафайла.

ОБРАБОТКА БИНАРНЫХ ДАННЫХ

Хотя Perl ориентирован в первую очередь на обработку текста, он также может обрабатывать бинарные данные. Скрипты могут перемещать бинарные данные частями, используя строковые переменные, и выполнять байтовые операции ввода/вывода, используя функции sysread и syswrite. Однако для того, чтобы выполнить что-нибудь<полезное> с данными, скрипт вынужден конвертировать данные в свои <родные> скалярные форматы.

ХРАНЕНИЕ БИНАРНЫХ ДАННЫХ

Когда скрипт на языке Perl читает блок бинарных данных, используя функцию sysread, он помещает эти бинарные данные в скалярную строковую переменную. Perl не заботится о том, что это заданные, содержат ли они нули или значения, не являющиесяASCII-символами. В пределах символьной строки Perl принимает байты как байты. В отличие от языка С, Perl не использует строк,оканчивающихся нуль-символом. Если данные соответствуют кодовойтаблице ASCII, то скрипт может их обрабатывать, как любой текст.Но если данные представляют собой бинарные величины, то скрипт обязан распаковать их перед тем, как Perl сможет обработать этиданные.

РАСПАКОВКА СТРОК БИНАРНЫХ ДАННЫХ В ПЕРЕМЕННЫЕ ЯЗЫКА PERL

Для того чтобы скрипт получил доступ к бинарным данным, ондолжен распаковать их, перейдя в свой скалярный формат. СкриптыPerl распаковывают данные, используя функцию unpack, котораяимеет следующий формат:

$result = unpack(Template, Expression);

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

($r, $g, $b) = unpack("C3", $color);# распакует в 3 символа
- @longwords = unpack("L*", $data); # распакует в список длинных # слов @stuff = unpack("S2L", $bin); # распакует в 2 shorts и long

Каждый символ шаблона может сопровождаться числом, указывающим, сколько раз использовать этот символ. Если вместо числа стоит звездочка (*), то операция будет выполняться для всех остающихся данных в строке. Если число не поставлено, то она выполняется однократно. Скрипт может поместить любое число символов шаблона в строку Template. В таблице 12.4 перечисляются символы,входящие в строковый параметр Template вместе с описанием влияния каждого из них на выполнение функции unpack.

Табл. 12.4. Символы шаблона

Символ шаблона Описание
a
А Строка ASCII без нулевого символа
b Битовая строка (младший бит идет первым)
В Битовая строка (старший бит идет первым)
с Однобайтовый символ со знаком
С Однобайтовый символ без знака
d Значение с плавающей запятой, двойной точности
f Значение с плавающей запятой, одинарной точности шаблона
h Строка шестнадцатиричных значений (младшие разряды идут первыми)
Н Строка шестнадцатиричных значений (старшие разряды идут первыми)
i Целое со знаком
I Целое без знака
l Целое со знаком типа long
L То же, только без знака
n Короткое целое
N Длинное целое
p Указатель на строку
s Короткое целое со знаком
S Короткое целое без знака
u Раскодировка строки
v Короткое целое
V Длинное целое
x Пропустить вперед один байт
X Пропустить назад один байт
@ Перейти на указанную позицию в строке

УПАКОВКА ДАННЫХ В БИНАРНЫЕ СТРОКИ

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

$result = pack(Template, List);

Следующий фрагмент программы иллюстрирует использование функции pack:

$color = pack("C3", $r, $g, $b); $data = pack("L*", @longword); $bin = pack("S2L", @stuff);

Функция pack использует те же самые символы шаблона, что и функция unpack, за исключением символов а. А, и, х, X, @.

РАБОТА С КАТАЛОГАМИ

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

ОТКРЫТИЕ, ЧТЕНИЕ И ЗАКРЫТИЕ КАТАЛОГОВ

Скрипты на языке Perl позволяют открывать и читать содержимое файлов. Точно так же эти скрипты открывают каталоги и читают имена содержащихся в них файлов. Для открытия каталога скрипты используют функцию opendir, передавая указатель каталога и путь к нему. Для чтения списка файлов, содержащихся в каталоге, скрипт использует функцию readdir. Наконец, для закрытия каталога используется функция closedir. Следующий фрагмент программы иллюстрирует использование функции readdir для того, чтобы вывести на экран список файлов в текущем каталоге:

Opendir(Dir, $INC) || die; while ($file = readdir(Dir)) { print "$file \n" } closedir(Dir);

В этом фрагменте используется переменная $INC для доступа к текущему каталогу. Изменяя $INC на $ARGV, скрипт выводит на экран список файлов, содержащихся в каталоге, который вы указали в командной строке.

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

$result = rewinddir(DirHandle); $result = telldir(DirHandle); $result = seekdir(DirHandle, Position);

ФОРМАТИРОВАННЫЙ ВЫВОД

В этой главе вы познакомились с несколькими способами форматирования выходных данных скрипта с помощью функции print. Аналогично языку С, Perl также поддерживает функции printf и sprintf.В дополнение Perl также поддерживает генерацию отчетов в форместолбцов, используя шаблоны форм.

ИСПОЛЬЗОВАНИЕ ФУНКЦИИ PRINT

В этой главе скрипты широко использовали функцию print. Кроме того, Perl обеспечивает специальные переменные, которые влияют на работу функции print. В таблице 12.5 кратко характеризуются эти специальные переменные.

Табл. 12.5. Специальные переменные, которые управляют функцией печати

Для использования этих специальных переменных достаточно просто присвоить им значения, которые вы хотите. Например, в следующем фрагменте программы используется переменная $ для того,чтобы задать сепаратор между элементами печати:

$, = "*"; @list = 1..10; print @list; # Выведет 1*2*3*4*5*6*7*8*9*10

Оказывается, что переменная $ на самом деле воздействует на все строки, а не только на те, которые выводятся на печать. Однако чаще всего вы будете использовать ее для того, чтобы изменить значение, выводимое функцией print.

ФОРМАТИРОВАННЫЙ ВЫВОД ДАННЫХ ФУНКЦИЕЙ PRINTF

Perl имеет функции printf и sprintf, которые очень похожи насоответствующие функции библиотеки времени выполнения языка С.Они имеют следующий формат: $result = printf( Format, List); $result = sprintf(Format, List);

По умолчанию функция printf посылает форматированный выходна стандартный выход STDIO, а функция sprintf возвращает форматированную строку. В обоих случаях формат строк почти аналогичен функциям языка С, исключая только отсутствие поддержки функциямиязыка Perl спецификатора длины (*). Следующий фрагмент программы иллюстрирует использование функций printf и sprintf.

$precision = 2; $pi = 3.1415; printf("%.2f\n", $pi); # выведет 3.14 printf("%.${precision}f", $pi); # выведет 3.14

ВЫЗОВ ВНЕШНИХ ПРОГРАММ ИЗ СКРИПТА НА ЯЗЫКЕ PERL

Будучи в известном смысле заменой скриптов shell, Perl обеспечивает поддержку системного взаимодействия, включая вызов внешних программ. В следующих разделах рассматривается несколько способов вызова внешних программ из скриптов Perl. Имейте, однако, ввиду, что позволяя скриптам выполнять системные команды, вы темсамым открываете бреши в системе безопасности вашего узла. Придерживайтесь общего правила не выполнять внешних команд из скрипта на языке Perl. Тем не менее, если вы вынуждены выполнять внешние команды из скрипта, то можете использовать для этих целейвстроенные функции system, exec или fork.

РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ

На протяжении этой главы вы познакомились с примерами функций для обработки строк. Многие из них основаны на концепции регулярных выражений. Как вы видите из следующих разделов, скрипты языка Perl широко используют регулярные выражения для обработки текста. Если регулярные выражения внове для вас, то не беспокойтесь. Спустя короткое время после того, как вы познакомитесь снесколькими разделами этой главы, регулярные выражения станут длявас просты и понятны.

ОБЗОР РЕГУЛЯРНЫХ ВЫРАЖЕНИЙ

Регулярные выражения являются причудливым термином, возникшим в компьютерной науке и служащим для обозначения образца, состоящего из символов. Скрипты на языке Perl используют символьныеобразцы просто для того, чтобы провести анализ входных данных,расщепляя их на части. Часто скрипт может проанализировать входные данные, основываясь на пробелах, запятых, символах табуляциии других разделителях. Но когда входные данные имеют произвольный формат то лучше всего с такой задачей справляются регулярные выражения.

СИНТАКСИС РЕГУЛЯРНЫХ ВЫРАЖЕНИЙ

Для сокращения размеров регулярных выражений, Perl использует специальные символы. Таблица 12.6 содержит список некоторых из символов, используемых скриптами языка Perl в регулярных выражениях.

Табл. 12.6. Символы, используемые в регумрных выражениях

Символ Описание
. Соответствует любому символу (за исключением символа новой строки)
(..) Группирует последовательность элементов
+ Удовлетворяет предыдущему образцу один или большее количество раз

-
Удовлетворяет образцу нуль или один раз
* Соответствует образцу один или нуль раз
[...] Соответствует символу из заданного множества
[^...] Соответствует символу из множества, полученного отрицанием
(...|...|...) Соответствует одной из альтернатив
^ Соответствует началу строки
$ Соответствует образцу в конце строки
{n,m} Соответствует образцу от n до m раз
{n} Соответствует образцу точно n раз
{n,} Соответствует образцу минимум n раз
\n\t etc. Соответствует знаку новой линии, символу табуляции и т. д.
\b Соответствует на границе слова
\B Соответствует внутри границ слова
\d Соответствует цифре
\D Соответствует не цифре
\s Соответствует пробелу
\S Соответствует не пробелу
\w Соответствует букве или цифре
\W Соответствует символу, не являющемуся ни буквой, ни цифрой

Perl помещает регулярные выражения (образцы, шаблоны) в слэши, т. е. в наклонные черточки, например, в виде /pattern/. Следующий фрагмент программы иллюстрирует регулярные выражения языка Perl:

# the following regular expressions are true if: /ig/ # string contains "ig" /(b|d|f)ig/ # string contains "big", "dig" or "fig" /+/ # string contains a number /*/ # string contains an identifier

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

ИСПОЛЬЗОВАНИЕ РЕГУЛЯРНЫХ ВЫРАЖЕНИЙ ДЛЯ ПОИСКА ПО КЛЮЧЕВЫМСЛОВАМ

Скрипты языка Perl используют регулярные выражения для того,чтобы упростить сравнение строк. Для того чтобы проверить, содержит ли строка заданный образец, скрипт может использовать регулярные выражения следующим образом:

If ($str =~ /pattern/)

В данном случае регулярные выражения принимают значение <истинно>, если образец найден в строке ($str). Если строка по содержит образца, то выражение возвращает значение <ложно>. Например, следующее выражение проверяет, содержит ли строка текст WebProgramming:

If ($str =~ /Web Programming/)

Для того, чтобы проверить полное совпадение, выражение должно привязать сравнение к началу и концу строки. Например, следующее выражение имеет значением величину <истинно>, если итолько если переменная $str принимает одно из трех значений:, ) :

($str =~ /^ba(na) {2,4}$/)

Аналогичным образом, следующее выражение истинно тогда итолько тогда, когда переменная $str содержит слово и не является частью другого слова, такого как .

($str =~ /\bthe\b/)

ИСПОЛЬЗОВАНИЕ РЕГУЛЯРНЫХ ВЫРАЖЕНИЙ ДЛЯ АНАЛИЗА ВХОДНЫХ ДАННЫХ

По мере усложнения ваших скриптов Perl возникнет много случаев, когда вы захотите узнать больше, чем просто проверить, совпадает ли образец со строкой или нет. Например, может потребоваться, чтобы скрипт извлек определенное значение строки.Используя символы группировки () внутри регулярного выражения,скрипт может извлечь соответствующие образцу значения из строки и сформировать из них список. Например, следующий фрагмент программы использует регулярные выражения для того, чтобы извлечь месяцы, дни и годы из списка:

$str = " January 1, 1997, "; ($m, $d, $y) = $str =~ /\s*(\S*)\s + (\d+)\D + (\d{4})/;


- Пропустить вначале любой специальный символ;
- записать все символы, не являющиеся специальными, в переменную $m
- (переменная для обозначения месяцев);
- пропустить специальный символ;
- поместить все цифры в переменную $d (переменная для записи дней);
- пропустить все знаки, не являющиеся цифрами;
- записать четыре цифры в переменную $у (переменная для обозначения лет).

Perl поддерживает также другую форму сравнения с образцом,использующую оператор (=~), который добавляет отрицание результата: (!~). Этот оператор эквивалентен выражению!($str=~/pattern/).

РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ ДЛЯ ПОИСКА И ЗАМЕНЫ СТРОК

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

$str =~ s/pattern/replacement/;

Например, следующая инструкция заменит слово на:

$str =~ s/\bcolour\b/color/;

Небольшая модификация позволяет заменить все слова на :

$str =~ s/\bcolour\b/color/g;

В данном случае g в конце выражения указывает языку Perl нанеобходимость глобальной подстановки.

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

$str =~ tr/SearchList/ReplacementList/;

Например, замена всех символов нижнего регистра теми же символами верхнею регистра может быть осуществлена таким образом:

$str =~ tr/a-z/A-Z/; # меняет регистр, с нижнего на верхний

Проанализируйте сами следующий пример:

$letters = "abcde"; print "$letters\n" # Выведет abcde $letters =~ tr/a-z/A-Z/; print "$letters\n" # Выведет ABCDE

РЕЗЮМЕ

В этой главе рассмотрено введение в программирование на языке Perl. Используя рассмотренные здесь концепции, можно писать сложные скрипты CGI на языке Perl. Следующая глава окажет вам помощь в получении навыков в создании CGI-скриптов на языке Perl,которые можно запустить на собственном сервере. Прежде чем следовать далее, удостоверьтесь, что вы понимаете следующие ключевыеконцепции:

Perl представляет собой интерпретируемый язык программирования,который используется программистами для написания скриптов дляWeb и Internet.

Конструкции языка Perl во многих отношениях напоминают аналогичные конструкции языка С, однако Perl предлагает много дополнительных возможностей, в особенности для обработки строк и файлов,которые трудно отыскать в языке С.

Perl является основным языком для написания CGI-программ дляWeb и Internet, в первую очередь благодаря своей гибкости, компактному стилю и обеспечению высокой безопасности.

ВАЖНЕЙШИЕ WEB-УЗЛЫ С ИНФОРМАЦИЕЙ О PERL

Следующие узлы Web помогут отыскать информацию об интересующих вас деталях относительно языка Pcrl, скриптов на нем, а также специальной информации о ресурсах языка Perl 5 и его библиотеках. Используйте эти Web-узлы в качестве отправной точки вашего поиска.

РЕЗЮМЕ

В этой главе вы познакомились с тем, как использовать Perlдля написания достаточно сложных скриптов CGI. Используя ту технику, с которой вы познакомились можете, услуги программиста профессионального уровня вашим клиентам, которые желали бы, чтобы их бизнес был представлен на Web. В главе 14 вы познакомитесь с языком Java. Как вы увидите, язык Java хорошо приспособлен для создания узлов Web, содержащих анимацию и мультимедиа. Дополнительно глава 14 представляет другой язык для написания скриптов JavaScript. Однако перед тем как переходить к главе 14, проверьте, понимаете ли вы следующие ключевые концепции:
- Perl представляет собой разносторонний и гибкий язык программирования, с помощью которого можно разрабатывать скрипты CGI для Web, а также традиционные программы для каждодневного использования.

  • Perl хорошо приспособлен для обработки текстов, организации доступа к базам данных, он является переносимым языком и обеспечивает безопасность при работе в сетях. Все эти его характеристики являются важными для Web программирования.
  • Для обработки текстов скрипты языка Perl широко используют регулярные выражения.
  • Большинство скриптов на Web в настоящее время написаны на языке Perl. Однако такие языки, как JavaScript и VBScript, могут посягнуть на монополию языка Perl.

Предисловие, на наш взгляд, должно дать читателю информацию, на основании которой он решает, нужна ли ему эта книга.

О чем наша книга. Она, естественно, о языке Perl, потому что так заявлено в названии. Кому он нужен, этот Perl? Тем, кто создает CGI-сценарии, занимается администрированием системы при помощи написания скриптов, а не щелкая левой кнопкой мыши, обрабатывает тексты, решает многие другие задачи из смежных областей и при этом нуждается в мощном, но простом в применении средстве, позволяющем создавать большие программы и маленькие программки и быстро их опробовать. Тем, кто преподает программирование, тоже полезно иметь представление об этом языке, так как он обладает интересными свойствами, отсутствующими в традиционных языках программирования, используемых в процессе обучения.

Нам нравятся некоторые особенности языка: зависимость результата от контекста, ассоциативные массивы, тип данных typeglob, пакеты, реализация объектно-ориентированного программирования и, конечно, средства обработки текста. Если вам не интересно хотя бы узнать, что все это означает, то можете книгу отложить. Если все перечисленное вам уже известно, то тоже можете ее отложить, потому что эта книга для тех читателей, кто еще только начинает изучать Perl самостоятельно.

Язык Perl создан системным программистом Ларри Уоллом (Larry Wall) как средство UNIX, позволяющее «склеивать» из программок, выполняющих отдельные функции, большие сценарии для решения комплекса задач, связанных с администрированием, обработкой текста и т. д. В дальнейшем он вышел за эти рамки, превратился в настоящий язык программирования, в котором нашли отражение многие тенденции, обозначившиеся в технологии программирования за последнее десятилетие, и получил широкое распространение в связи с развитием Inernet. Perl является основным средством создания приложений CGI, удобен для решения задач администрирования Web-серверов, электронной почты и других систем. Благодаря быстроте и легкости написания сценариев на этом языке он распространился и на другие платформы: DOS, Windows, OS/2, Mac, VMS и пр. Одно из основных достоинств языка Perl - его открытость и доступность. В сети Internet можно получить совершенно бесплатно исходные тексты интерпретатора perl (язык Perl - интерпретируемый, что в некоторых случаях является преимуществом) и модулей его расширения.

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

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

Сразу нужно пояснить, для кого это все написано. Если Ваш сервер работает на платформе UNIX, то это я должен читать Вашу статью. У меня же установлен Windows NT workstation 4.0 (RUS) плюс Service Pack 3. Когда пришло время сделать из компьютера WEB-сервер, я было кинулся ко встроенным Службам узла WEB, но быстро понял, что это мне не нравится (почему?). И тут один добрый человек посоветовал поставить Xitami WEB Server от iMatix Corporation (http://www.imatix.com/), который и стоит по сей день.

Что касается самого Перла, то здесь несколько сложнее. Покопавшись по различным Перловым серверам (www.perl.org , www.perl.com) я узнал, что версий Перла настолько много, что выбрать что-нибудь конкретное довольно сложно. При этом каких-нибудь вразумительных рекомендаций по поводу выбора той или иной версии нигде нет. Перепробовав почти все версии для Windows, я остановил свой выбор на Active Perl (http://www.activestate.com/).

Человеку, избалованному всякими Виндовозами и Дельфями, писать программы на Перл довольно непривычно, поэтому настоятельно рекомендую сразу установить Perl Builder. Взять его можно на www.solutionsoft.com. Там лежала тридцатидневная Демо версия.

Ну, думаю, пора переходить непосредственно к делу. В общем случае, скрипт на Перл, как и любая другая программа, работает так:

  1. получает данные
  2. обрабатывает данные
  3. выдает результаты

Передать данные скрипту можно двумя методами - GET и POST. Разница между ними в том, что при использовании GET данные постоянно болтаются в строке адреса браузера, напимер:

Httр://treagraf.tasur.edu.ru/cgi-bin/price.pl?Category=POWER&Description=varta

В этом случае скрипт B_price.pl берет данные в переменной окружения QUERY-STRING.

$data=$ENV{"QUERY_STRING"};

При использовании метода POST данные передаются на стандартный вход скрипта. Длинна блока данных берется в переменной CONTENT_LENGTH:

Read(STDIN,$data,$ENV{"CONTENT_LENGTH"});

Теперь эти данные нужно перевести в удобоваримый вид, поскольку они закодированы.

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

Http://treagraf.tasur.edu.ru/cgi-bin/B_price.pl?Category=%C2%E8%E4%E5%EE&Description=%E0%E1%E2%E3

Это значит:

Http://treagraf.tasur.edu.ru/cgi-bin/B_price.pl?Category=Видео&Description=абвг

Декодировать строку запросов в первый раз лучше самому. На вопрос "а как?" есть множество ответов, переписывать которые нет смысла. Приведу лишь короткий пример:

Заменяем знаки (+) на пробелы

$query = ~ s/\+/ /g;

Потом заменяем все сочетания знака (%), после которого следуют шестнадцатиричные цифры, на соответствующий символ ASCII

$query =~ s/%({2})/pack("C", hex($1))/eg;

Я пользуюсь тем, что предлагает Perl Builder:

#! E:\perl5\bin\perl &GetFormInput; # вызов подпрограммы получения данных $Category = $field{"Category"}; # получаем данные из поля Category $Description = $field{"Description"}; # получаем данные из поля Description $Page = $field{"Page"}; # получаем данные из поля Page

В конце скрипта помещаем подпрограмму "прозрачного" чтения данных.

Sub GetFormInput { (*fval) = @_ if @_ ; local ($buf); if ($ENV{"REQUEST_METHOD"} eq "POST") { read(STDIN,$buf,$ENV{"CONTENT_LENGTH"}); } else { $buf=$ENV{"QUERY_STRING"}; } if ($buf eq "") { return 0 ; } else { @fval=split(/&/,$buf); foreach $i (0 .. $#fval){ ($name,$val)=split (/=/,$fval[$i],2); $val=~tr/+/ /; $val=~ s/%(..)/pack("c",hex($1))/ge; $name=~tr/+/ /; $name=~ s/%(..)/pack("c",hex($1))/ge; if (!defined($field{$name})) { $field{$name}=$val; } else { $field{$name} .= ",$val"; #if you want multi-selects to goto into an array change to: #$field{$name} .= "\0$val"; } } } return 1; }

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

И, наконец, Вам нужно выдать какие-то результаты броузеру клиента, причем так, чтобы броузер правильно их отобразил. То есть, выдавать результаты нужно в HTML. Это делается просто: (тоже можно по-разному)

Print "Content-type: text/html", "/n/n"; #обязательная строка print "

В поле Category Вы ввели: ", $Category, "

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

  1. При первом запуске скрипт рисует HTML страницу с формой и ссылкой в тэге ACTION на самого себя. Первый запуск определяется по отсутствию входных данных.
  2. Если входные данные есть, то получаем их, обрабатываем и выдаем результаты.

#! E:\perl5\bin\perl if (($ENV{"QUERY_STRING"} eq "") or ($ENV{CONTENT_LENGTH}=0)) { # генерируем страницу с формой } else {# получаем данные, обрабатываем и выдаем результат}

Гостевая книга

Общий алгоритм работы гостевой книги таков:

1. Если посетитель хочет сделать запись в книгу, то
1.1 Получаем данные
1.2 Записываем их в файл или в базу данных
1.3 Говорим спасибо на HTML и предлагаем почитать другие записи
2. Если посетитель хочет почитать записи в книге, то
2.1 Читаем записи из файла или из базы данных
2.2 Выводим их красиво в HTML

Для удобства восприятия я оформил пункты 1 и 2 отдельными скриптами add_guestbook.pl и read_guestbook.pl соответственно. Сообщения гостевой книги хранятся в текстовом файле построчно, т.е. на каждую запись - строка. Так сделано для удобства чтения этого файла. Пример одной записи:

Sat Dec 5 13:31:20 1998&Наташа&студентка&Good&Для начала хорошо. Успехов на данном поприще Вам, Александр!&нету@пока&194.226.60.34

Вот описание полей рассматриваемой гостевой книги.
Name - имя, фамилия, отчество, кличка - на усмотрение посетителя
Work - профессия, род занятий
RadioButton - три кнопки: понравилось (Good), не понравилось (Bad), пофигу (Different)
Text - text box комментариев и примечаний
Email - обратный адрес

add_guestbook.pl - запись в книгу

#! e:\perl5\perl # Первая строка, как обычно require "ssi-pl.pl"; # Я использую навигационную панель в виде SSI-включения. Для этого используется модуль ssi-pl.pl if (($ENV{"QUERY_STRING"} eq "") or ($ENV{CONTENT_LENGTH}=0)) { # Если нет входных данных, то генерируем страницу с формой print < Книга жалоб и предложений

HTML DoInclude("_menu.htm"); # Это SSI-включение навигационной панели. print <

Я, , по профессии простой , посетив данный сервер и ознакомившись с представленными на нем материалами, хочу выразить свои чувства и эмоции следующими приличными словами:

мне понравилось:-)

мне не понравилось:-(

мне пофигу:-|

В дополнение к сказанному хочу так же сказать:

Прошу принять к рассмотрению мое заявление и незамедлительно принять меры. Решение по моему заявлению направить письменно на мой электронный адрес .

HTML die; } # Теперь получаем входные данные. &GetFormInput; $Name = $field{"Name"} ; $Work = $field{"Work"} ; $RadioButton = $field{"RadioButton"} ; $Text = $field{"Text"} ; $Email = $field{"Email"} ; $Send = $field{"Send"} ; # это поле не используется # Проверяем, заполнены ли обязательные поля. # Если нет - генерируем HTML страницу с просьбой заполнить нужные поля. if ($Name eq "" || $Email eq "" || $Text eq "") { print < Книга жалоб и предложений - ошибка

<

Вы не указали свое имя, E-mail, либо не заполнили сам текст Вашего отзыва. Вернитесь, пожалуйста, на страницу формы и заполните требуемые поля.

Назад

HTML } else # все данные правильно введены { # Если все поля заполнены правильно, то начинаем их обрабатывать. $Text=~tr/\r\n/ /; #заменяем перевод строки на пробел # Если в текстовом поле формы (text box) посетитель нажимал Enter, # то нужно убрать символы перевода строки, чтобы можно было записать # все поля формы в одну строку файла. if ($Work eq "") {$Work=" "}; #если пусто - то пробел # Если поле не заполнено, то оно равно пробелу. $Name=~s/&/ /g; $Work=~s/&/ /g; $Text=~s/&/ /g; $Email=~s/&/ /g; # Если посетитель использовал символ &, то заменяем его на пробел, # поскольку этот символ мы будем использовать для разделения наших полей в файле. open(OutFile, ">>guestbook.txt") || die; # Открываем файл для добавления. $Time=localtime; #получаем время # Получаем время заполнения гостевой книги. $line=join("&", $Time, $Name, $Work, $RadioButton, $Text, $Email, $ENV{REMOTE_HOST}); # И, наконец, слепляем все поля формы в одну строку. На всякий случай добавляем в конце # IP адрес посетителя, взятый из переменных окружения. print OutFile "$line\n"; close OutFile; # Записываем полученную строку в файл и закрываем его. # Осталось только сказать посетителю спасибо. # выводим сообщение о успехе print "Content-type: text/html\n\n"; print "\n" ; print "\n" ; print "\n" ; print ""."\n" ; print ""."\n" ; print "Книга жалоб и предложений\n" ; print "\n" ; print "\n" ; print ""."\n" ; print "
"."\n" ; print "\n" ; print ""."\n" ; print " \n" ; print " "."\n" ; print " "."\n" ; print " \n" ; print "

"; print "

\n" ; print "
"."\n" ; print "\n" ; print ""."\n" ; print " \n" ; print " "."\n" ; print " "."\n" ; print " "."\n" ; print " \n" ; print "

"."\n" ; DoInclude("D:/InetPub/wwwroot/_menu.htm"); print "

Ваши данные"."\n" ; print " приняты. Спасибо.

\n" ; print "

"; print "

\n" ; print "
\n" ; print "\n" ; print "\n" ; print " \n" ; print " "."\n" ; print " \n" ; print "
\n" ; print "\n" ; print "\n" ; } # Не забываем подпрограмму разбора данных из формы. sub GetFormInput { (*fval) = @_ if @_ ; local ($buf); if ($ENV{"REQUEST_METHOD"} eq "POST") { read(STDIN,$buf,$ENV{"CONTENT_LENGTH"}); } else { $buf=$ENV{"QUERY_STRING"}; } if ($buf eq "") { return 0 ; } else { @fval=split(/&/,$buf); foreach $i (0 .. $#fval){ ($name,$val)=split (/=/,$fval[$i],2); $val=~tr/+/ /; $val=~ s/%(..)/pack("c",hex($1))/ge; $name=~tr/+/ /; $name=~ s/%(..)/pack("c",hex($1))/ge; if (!defined($field{$name})) { $field{$name}=$val; } else { $field{$name} .= ",$val"; #if you want multi-selects to goto into an array change to: #$field{$name} .= "\0$val"; } } } return 1; }

read_guestbook.pl - чтение книги

#! e:\perl5\perl # Первая строка, как обычно require "ssi-pl.pl"; # Я использую навигационную панель в виде SSI-включения. Для этого используется модуль ssi-pl.pl open(InFile, "guestbook.txt") || die; # Открываем файл с записями гостевой книги. @lines=; # Читаем строки в массив. # Выдаем шапку HTML страницы. print < Книга жалоб и предложений - нам пишут

HTML DoInclude("D:/InetPub/wwwroot/_menu.htm"); print <

Нам пишут:

HTML # Теперь выводим записи в невидимой (в смысле, рамка не видима) таблице. # Чтобы свежие записи отображать первыми, обрабатываем массив строк с конца. for ($i=$#lines; $i>=$[; $i--) #обрабатываем строки файла с конца { # Разделяем строку на части @item=split("&", $lines[$i]); #разделяем на части # Теперь заменяем HTML тэги в записи (на случай какого-нибудь хитрого юзера) foreach (@item) { $_=~s//>/g; } # Приступаем непосредственно к выводу записей в HTML print "\n"; print "\n"; print "\n"; } # Осталось вывести окончание HTML print <
"."\n"; # В зависимости от поля, где посетителю предлагался выбор понравилось - не понравилось, # рисуем картинку с веселой или грустной мордочкой соответственно. В качестве ALT тэга # картинки пропишем IP адрес посетителя. print "
"." ".$item."
\n"; print "
".$item.", ".$item."
\n"; print "
".$item."
"."\n"; print "
".$item."
\n"; print "
\n"; print "
HTML close InFile; # Закрываем файл с записями гостевой книги.

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

Вы владеете какими-либо другими языками программирования? Если да, то изучение Perl будет для вас просто удовольствием. Если же нет, то не спешите, пробуйте все предлагаемые упражнения и примеры и не бойтесь экспериментировать!

Происхождение

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

Одна из причуд языка - его название. Оно имеет несколько определений. Первоначально Perl означал Practical Extraction Report Language (практический язык извлечений и отчетов). Однако, программисты очень часто называют его Phatologically Eclectic Rubbish Lister или даже Practically Everything Really Likable.

Давайте посвятим несколько минут тому, чтобы разобраться, что представляет собой Perl, и какие задачи возлагались на него во времена его создания. В далеком 1986 году Larry Wall работал над задачей генерирования отчетов из большого количества текстовых файлов, пересекающихся друг с другом. Будучи Unix-программистом, а также, потому что задача включала в себя манипулирование содержанием текстовых файлов, он первым делом попытался использовать Awk. Но вскоре стало ясно, что Awk для работы не подходит, и, не имея других кандидатов для решения поставленной задачи, оставалось только изобретать свой собственный инструмент, который можно было бы использовать и в будущем.

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

Вскоре Larry предложил свое детище сообществу читателей материалов телеконференций Usenet. Пользователи, имеющие доступ к Usenet, обеспечили создателю Perl эффективную "обратную поддержку", спрашивая, как делать одно, другое, третье. Многие из этих задач Larry даже и не собирался ставить перед своим маленьким новым языком программирования.

Новый язык программирования имел акцент на управление системой и обработку текста. После нескольких пересмотров он уже мог использовать регулярные выражения, сигналы, а также сетевые сокеты. Он стал известен как Perl и очень быстро сделался популярным в среде Unix-программистов, а вскоре и у всех нас.

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

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

Perl призван помочь программисту в выполнении рутинных задач, которые для shell слишком трудны или плохо переносимы, а для Си (или любого другого языка) - слишком заумны или сложны в кодировании.

Когда вы освоите Perl, вы, возможно, обнаружите, что стали тратить заметно меньше времени на правильное заключение в кавычки различных параметров shell (или на корректное выполнение Си-объявлений), а больше - на чтение Usenet-новостей и катание с гор на лыжах, потому что Perl - замечательное средство для вашего совершенствования как программиста. "Кто-то из древних" сказал: "Не стОит изучать язык программирования, который радикально не меняет вашего представления о программировании". Будьте уверены - изучив Perl, вы посмотрите на программирование с совершенно иной точки зрения.

Мощные конструкции этого языка позволяют создавать с минимальной затратой сил очень эффективные решения и универсальные инструменты. Эти инструменты можно использовать и в дальнейшем, потому что написанные на Perl программы отличаются высокой переносимостью и готовностью к использованию. В результате у вас появится еще больше времени для чтения Usenet-новостей и посещения с друзьями баров.

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

Стоимость и лицензия

Perl свободен. Если быть более точным - Perl распространяется по открытой лицензии GNU (GNU Public License). Полный исходный код и документация абсолютно свободны для копирования, компилирования и печати. Все программы, написанные вами на Perl - ваши, и вы можете делать с ними все что захотите.

Помимо UNIX-компьютеров, Perl также существует для других платформ, - Windows, DOS, Atari, Amiga и.д.

Проинсталлирован ли у вас Perl?

Очень легко узнать, есть ли у вас Perl. Просто дайте в командной строке следующую команду:

perl -v This is perl, version 5.001
Unofficial patchlevel 1m.
Copyright 1987-1994, Larry Wall Win32 port Copyright 1995 Microsoft Corporation. All rights reserved.
Developed by hip communications iNC., //info.hip.com/info/
Perl for Win32 Build 107
Built Apr 16 1996@14:47:22
Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5.0 source kit.

Если же вы получили сообщение об ошибке или у вас Perl четвертой версии, то обратитесь к вашему системному администратору или же установите Perl сами.

Ваша первая программа на Perl

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

Создание программы

Perl-программа представляет из себя обычный текстовый файл, содержащий несколько конструкций языка. Последние обычно напоминают смесь из Си, Unix shell script и английского языка. В общем-то, именно так оно и есть на самом деле.

Perl-код может быть достаточно разнообразным. Вот несколько основных правил:

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

Конструкция языка должна заканчиваться точкой с запятой, за исключением случаев, когда данная конструкция является последней в блоке или файле, или это - оператор eval;

Пробелы, табуляция, пустые строки иррелевантны, - один пробел также хорош, как сто таких же пробелов. Это означает, что вы можете разбивать конструкцию языка на несколько строк для ясности. Строка - это обычно серия символов, заключенных в кавычки. Глава 2 "Числовые и строковые литералы" содержит более подробное описание строк;

Все что следует за символом "#" игнорируется, если только это не внутри какой-либо строки. Используйте эту возможность для обеспечения вашего кода полезными комментариями. Надо отметить, что многострочных комментариев (например, как в языке Си) в Perl нет.

Аналогично shell-скрипту, Perl-программа состоит из всех операторов Perl, имеющихся в файле и рассматриваемых в совокупности как одна большая программа, подлежащая выполнению. Понятия main-функции, как в Си, в Perl нет.