The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME/НАИМЕНОВАНИЕ

perlintro - Краткое введение и обзор Perl

ОПИСАНИЕ

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

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

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

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

Эти примеры часто отражают стиль и предпочтения автора этой части документации и могут быть короче, чем соответствующая строка кода в реальной программе. Если не оговорено иное, следует предполагать, что объявления use strict и use warnings уже есть в заголовке программы, и что любые переменные, используемые уже были объявлены, даже если эти декларации были опущены, чтобы сделать пример проще для чтения.

Нельзя не отметить, что примеры были написаны многими разными авторами в течение нескольких десятилетий. Стили и методы будут таким образом отличаться, хотя некоторые усилия были предприняты, чтобы стили не менялись слишком широко в одном разделе. Не считайте один стиль лучше, чем другие - "Есть более чем один способ сделать это" ("There's More Than One Way To Do It" ) является одним из девизов Perl. В конце концов, в вашем путешествии, как программиста, вы, вероятно, столкнётесь с различными стилями.

Что такое Perl?

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

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

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

Запуск Perl программ

Чтобы запустить программу Perl из командной строки Unix:

 perl progname.pl

Кроме того, вставьте это в первую строку вашего скрипта:

 #!/usr/bin/env perl

... и запустить скрипт как /path/to/script.pl. Конечно файлу нужно дать права на исполнение, поэтому chmod 755 script.pl (under Unix).

(Это первая строка подразумевает, что у вас есть программа env. Вы также можете поместить непосредственно путь к исполняемому файлу perl, например, #!/usr/bin/perl).

Для получения дополнительной информации, в том числе инструкций для других платформ, таких как Windows и Mac OS, читайте perlrun.

Подушка безопасности

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

 #!/usr/bin/perl
 use strict;
 use warnings;

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

Основной обзор синтаксиса

Perl скрипт или программа состоит из одного или нескольких операторов. Эти операторы(statements) просто написаны в сценарии прямым способом. Здесь нет необходимости иметь main() функцию или что-нибудь в этом роде.

Perl операторы имеют в конце точку с запятой:

 print "Привет, мир";

Комментарии начинаются с хэш-символа '#' и продолжаются до конца строки

 # Это комментарий

Пробелы не имеют значения:

 print
     "Привет, мир!"
     ;

... кроме внутри строки в кавычках:

 # это будет печатать с переносом строки по середине
 print "Привет
 мир";

Двойные или одинарные кавычки могут быть использованы вокруг символьных строк:

 print "Привет, мир";
 print 'Привет, мир';

Однако, только двойные кавычки "интерполируют" переменные и специальные символы, такие как символы новой строки (\n):

 print "Hello, $name\n";     # работает отлично
 print 'Hello, $name\n';     # печатает $name\n буквально

Числа не нуждаются в кавычках вокруг них:

 print 42;

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

 print("Hello, world\n");
 print "Hello, world\n";

Более подробные сведения о синтаксисе Perl можно найти в perlsyn .

Perl типы переменных

Perl имеет три основных типа переменных: скаляры, массивы и хэши.

Скаляры

Скаляр представляет одно значение:

 my $animal = "camel";
 my $answer = 42;

Скалярные значения могут быть строки, целые числа или числа с плавающей точкой, а также Perl автоматически преобразует между ними по мере необходимости. Здесь нет необходимости предварительно объявлять переменную типа, но вы должны объявить их с помощью ключевого слова my ,если вы используете их в первый раз. (Это одно из требований use strict; ).

Скалярные значения могут быть использованы в различных формах:

 print $animal;
 print "The animal is $animal\n";
 print "The square of $answer is ", $answer * $answer, "\n";

Есть целый ряд "магических" скаляров с именами, которые выглядят как знаки препинания или помехи в линиях. Эти переменные используются для всех видов целей, и документированы в perlvar . Единственное, что вам нужно знать о этом на данный момент, то это про переменную $_ которая является "переменной по умолчанию". Она используется как аргумент по умолчанию для ряда функций в Perl, и устанавливается неявно в определенные циклические конструкции.

 print;          # Выводит содержимое $_ по умолчанию
Массивы

Массив представляет собой список значений:

 my @animals = ("camel", "llama", "owl");
 my @numbers = (23, 42, 69);
 my @mixed   = ("camel", 42, 1.23);

Массивы индексируются с нуля. Вот как вы можете вытащить элемент массива:

 print $animals[0];              # печатает "camel"
 print $animals[1];              # печатает "llama"

Специальная переменная $#array говорит вам, индекс последнего элемента массива:

 print $mixed[$#mixed];       # последний элемент, печатает 1.23

Можно было бы попытаться использовать $#array + 1, чтобы сказать вам, сколько элементов есть в массиве. Не беспокойтесь. Как это происходит, используя @array, где Perl ожидает найти скалярное значение ("в скалярном контексте") даст вам количество элементов в массиве:

 if (@animals < 5) { ... }

Элементы, которые мы получаем из массива начинаются с $, потому что мы получаем только одно значение из массива, вы запрашиваете в скалярном контексте и таким образом получаете скаляр.

Чтобы получить несколько значений из массива:

 @animals[0,1];                 # дает ("camel", "llama");
 @animals[0..2];                # дает ("camel", "llama", "owl");
 @animals[1..$#animals];        # дает все, кроме первого элемента

Это называется "срез массива".

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

 my @sorted    = sort @animals;
 my @backwards = reverse @numbers;

Есть несколько специальных массивов также, такие как @ARGV (аргументы командной строки в скрипте) и @_ (аргументы, передаваемые в подпрограмму). Они описаны в perlvar.

Хэши

Хэш представляет собой набор пар ключ/значение:

 my %fruit_color = ("apple", "red", "banana", "yellow");

Можно использовать пробелы и оператору =>, чтобы выложить их для более наглядного представления:

 my %fruit_color = (
     apple  => "red",
     banana => "yellow",
 );

Чтобы добраться до элементов хэша:

 $fruit_color{"apple"};           # дает "red"

Вы можете получить в списки ключей и значений используя функции keys() и values() .

 my @fruits = keys %fruit_colors;
 my @colors = values %fruit_colors;

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

Так же, как специальные скаляры и массивы, существуют также специальные хэши. Наиболее известным из них является %ENV, который содержит переменные окружения. Читайте об этом (и других специальных переменных) в perlvar.

Скаляры, массивы и хэши описаны более полно в perldata .

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

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

 my $variables = {
     scalar  =>  {
                  description => "single item",
                  sigil => '$',
                 },
     array   =>  {
                  description => "ordered list of items",
                  sigil => '@',
                 },
     hash    =>  {
                  description => "key/value pairs",
                  sigil => '%',
                 },
 };

 print "Скаляры начинаются с $variables->{'scalar'}->{'sigil'}\n";

Исчерпывающую информацию по теме ссылок можно найти в perlreftut, perllol, perlref and perldsc.

Видимость переменной

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

 my $var = "value";

my на самом деле не требуется, вы можете использовать только:

 $var = "value";

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

 my $x = "foo";
 my $some_condition = 1;
 if ($some_condition) {
     my $y = "bar";
     print $x;           # prints "foo"
     print $y;           # prints "bar"
 }
 print $x;               # печатает "foo"
 print $y;               # ничего не печатает; $y выпал из сферы видимости переменной

Использование my в комбинации с use strict; в верхней части вашего Perl скрипта означает, что интерпретатор будет находить некоторые общие ошибки программирования. Например, в приведенном выше примере, конечный print $y приведет к ошибке времени компиляции и препятствует запуску программы. Использование strict настоятельно рекомендуется.

Условные и циклические конструкции

Perl имеет большинство обычных условных и циклических конструкций. По состоянию на Perl 5.10, у него даже есть оператор case/switch (пишется given/when). См. "Switch Statements" in perlsyn для более подробной информации.

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

if
 if ( условие ) {
     ...
 } elsif ( другое условие ) {
     ...
 } else {
     ...
 }

Здесь даже есть негативная версия этого оператора:

 unless ( условие ) {
     ...
 }

Это считается более читаемой версией if (!condition).

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

 # Традиционным способом
 if ($zippy) {
     print "Yow!";
 }

 # Perlish постусловный путь
 print "Yow!" if $zippy;
 print "We have no bananas" unless $bananas;
while
 while ( condition ) {
     ...
 }

Также есть негативная версия, по той же причине у нас есть unless :

 until ( condition ) {
     ...
 }

Вы также можете использовать while в пост-условии:

 print "LA LA LA\n" while 1;          #  зацикливается навсегда
for

Точно так же как C:

 for ($i = 0; $i <= $max; $i++) {
     ...
 }

Стиль С для цикла требуется редко Perl, т.к. Perl предоставляет более дружественный оператор для прохождения по списку foreach.

foreach
 foreach (@array) {
     print "Это элемент $_\n";
 }

 print $list[$_] foreach 0 .. $max;

 # вы не обязаны использовать переменную по умолчанию $ _ либо ...
 foreach my $key (keys %hash) {
     print "Значение $key есть $hash{$key}\n";
 }

Ключевое слово foreach на самом деле является синонимом ключевое слова for. См. "Foreach Loops" in perlsyn.

Более подробную информацию о конструкции цикла (и некоторые, которые не были упомянуты в этом обзоре) см. perlsyn.

= Head2 Встроенные операторы и функции

Perl поставляется с широким выбором встроенных функций. Некоторые из них, которые мы уже видели, включают print, sort and reverse. Их список приведен в начале perlfunc и вы можете легко прочитать о любой функции с помощью perldoc -f имя функции.

Perl операторы полностью описаны в perlop , но вот некоторые из наиболее распространенных из них:

Арифметические
 +   сложение
 -   вычитание
 *   умножение
 /   деление
Числовое сравнение
 ==  равенство
 !=  неравенство
 <   меньше чем
 >   больше чем
 <=  меньше или равно
 >=  больше или равно
Сравнение строк
 eq  равенство
 ne  неравенство
 lt  меньше
 gt  больше
 le  меньше или равно
 ge  больше или равно

(Почему у нас есть отдельные числовые и строковые сравнения? Потому что у нас нет специальных типов переменных и Perl должен знать, нужно ли сортировать численно (где 99 меньше 100) или в алфавитном порядке (100, где идет перед 99).

Булева логика (в честь Джорджа Була)
 &&  и
 ||  или
 !   отрицание

(and, or и not не только в приведенной выше таблице, также смотри описания операторов. Они также поддерживаются как операторы в их собственном виде. Они более понятные, чем C-style операторы, но имеют разные предпочтения (старшинство операторов) && и друзьями. Проверьте perlop для больших подробностей.)

Разное
 =   присваивание
 .   конкатенации строк
 x   умножение строк
 ..  оператор диапазона (создает список чисел)

Многие операторы могут быть объединены с = следующим образом:

 $a += 1;        # также как $a = $a + 1
 $a -= 1;        # также как $a = $a - 1
 $a .= "\n";     # также как $a = $a . "\n";

Файлы и Ввод/Вывод

Вы можете открыть файл для ввода или вывода с помощью функции open(). Это описано в экстравагантных деталях в perlfunc и perlopentut , но в кратце:

 open(my $in,  "<",  "input.txt")  or die "Can't open input.txt: $!";
 open(my $out, ">",  "output.txt") or die "Can't open output.txt: $!";
 open(my $log, ">>", "my.log")     or die "Can't open my.log: $!";

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

 my $line  = <$in>;
 my @lines = <$in>;

Чтение в файла целиком за один раз, называется slurping хлебать (съесть целиком). Это может быть полезным, но это может иметь память свиньи. Большинство средств обработки текстовых файлов можно сделать с помощью циклических конструкций Perl.

Оператор <> чаще всего используется в цикле while:

 while (<$in>) {     # присваивает каждой строке $_
     print "Just read in this line: $_";
 }

Мы уже видели, как печатать на стандартный вывод с помощью print(). Тем не менее, print() может также взять дополнительный первый аргумент, указывающий на дескриптор файла для печати:

 print STDERR "This is your final warning.\n";
 print $out $record;
 print $log $logmessage;

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

 close $in or die "$in: $!";

Регулярные выражения

Поддержка регулярных выражений Perl является как широкой и глубокой, и является предметом длинной документации в perlrequick, perlretut , И в других местах. Тем не менее, коротко:

Простое совпадение
 if (/foo/)       { ... }  # верно если $_ содержит "foo"
 if ($a =~ /foo/) { ... }  # верно если $a содержит "foo"

Оператор соответствия // описан в perlop. Он работает с $_ по умолчанию, или может быть связан с другой переменной с помощью оператора привязки =~ (также документированы в perlop).

Простая замена
 s/foo/bar/;               # заменяет foo с bar в $_
 $a =~ s/foo/bar/;         # заменяет foo с bar в $a
 $a =~ s/foo/bar/g;        # заменены ВСЕ ЭКЗЕМПЛЯРЫ foo с bar
                           # в $a

Оператор замены s/// описан в perlop

Более сложные регулярные выражения

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

 .                   один символ
 \s                  пробелы (пробел, табуляция, новая строка,
                     ...)
 \S                  непробельный символ
 \d                  цифра (0-9)
 \D                  нецифра non-digit
 \w                  символ слова (a-z, A-Z, 0-9, _)
 \W                  несловесный символ
 [aeiou]             соответствует одному символу в данном наборе
 [^aeiou]            соответствует одному символу вне данного набора
                     набор
 (foo|bar|baz)       соответствует любому из указанных альтернатив

 ^                   начало строки
 $                   конец строки

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

 *                   ноль или более от предыдущей вещи
 +                   один или более от предыдущей вещи
 ?                   ноль или один от предыдущей вещи
 {3}                 соответствует ровно 3 от предыдущей вещи
 {3,6}               соответствует между 3 и 6 от предыдущей вещи
 {3,}                соответствует 3 или более от предыдущей вещи

Некоторые краткие примеры:

 /^\d+/              строка начинается с одной или несколькими цифрами
 /^$/                ничего в строке (начало и конец
                     смежный)
 /(\d\s){3}/         три цифры, за каждой из которых стоит пробел
                     символ (например "3 4 5 ")
 /(a.)+/             соответствует строка, в которой каждый нечетный
                     письма (например, "abacadaf")

 # Этот цикл читает со стандартного ввода и печатает без пустых строк:
 while (<>) {
     next if /^$/;
     print;
 }
Скобки для захвата

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

 # дешевая и противная способ разорвать адрес электронной почты на части

 if ($email =~ /([^@]+)@(.+)/) {
     print "Username is $1\n";
     print "Hostname is $2\n";
 }
Другие функции регулярных выражений

Perl регулярные выражения также поддерживают обратные ссылки, lookaheads, и все виды других сложных деталей. Прочитайте все о них в perlrequick, perlretut, and perlre.

Написание подпрограмм

Написание подпрограмм легко:

 sub logger {
    my $logmessage = shift;
    open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
    print $logfile $logmessage;
 }

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

 logger("У нас есть регистратор подпрограммы!");

Что такое shift? Ну, аргументы подпрограммы доступны нам как специальный массив @_ (см. perlvar более подробно об этом). Аргумент по умолчанию в shift вытаскивает первый аргумент массива @_. Таким образом my $logmessage = shift; двигает первый пункт из списка аргументов и присваивает его $logmessage.

Мы можем управлять @_ и в других случаях тоже:

 my ($logmessage, $priority) = @_;       # общие
 my $logmessage = $_[0];                 # редко, и уродливо

Подпрограммы могут также возвращать значения:

 sub square {
     my $num = shift;
     my $result = $num * $num;
     return $result;
 }

Затем использовать его как:

 $sq = square(8);

Для получения дополнительной информации о написании подпрограмм см. perlsub.

OO Perl

OO Perl относительно проста и осуществляется с помощью ссылок, которые знают на основе какого объекта они созданы, объекты основаны на концепции Perl-пакетов. Тем не менее, OO Perl в значительной степени выходит за рамки этого документа. Читайте perlootut и perlobj.

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

Использование Perl модулей

Perl модули предоставляют широкий спектр функций, которые помогут вам не изобретать велосипед, их можно загрузить с CPAN (http://www.cpan.org/). Ряд популярных модулей уже идет в комплекте с Perl.

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

Чтобы узнать, как установить модули, загруженные из CPAN, читайте perlmodinstall .

Чтобы узнать, как использовать конкретный модуль, используйте perldoc Module::Name. Обычно вы можете использовать объявление use Module::Name, которое дает вам доступ к экспортируемым функциям или OO ориентированный интерфейс к модулю.

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

perlmod описывает Perl модулей в целом. perlmodlib список модулей, которые поставляются вместе с Perl установкой.

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

АВТОР

Kirrily "Skud" Robert <skud@cpan.org>

ПЕРЕВОДЧИКИ

  • Николай Мишин <mishin@cpan.org>