НАЗВА

perlintro - швидке введення та огляд мови Perl

ОПИС

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

Це введення не намагається бути вичерпним. Воно навіть не завжди точне. У деяких випадках, точність принесено в жертву на догоду тлумачення загальної ідеї. Дуже рекомендуємо супроводжувати це введення додатковою інформацією із повного посібника Perl, таблицю зі змістом якого можна знайти в ?perltoc(1).

У цьому документі ви нерідко знайдете посилання на інші частини документації Perl. Ви можете прочитати ці сторінки за допомогою команди ?perldoc(1), чи будь-якою іншою методою, за допомогою якої ви читаєте цей документ.

Що таке Perl?

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

Perl задумано як практичну (легку у використанні, ефективну, функціональну), а не гарну (маленьку, елегантну, мінімальну) мову. Її головними рисами є те, що нею легко користуватися, вона підтримує як процедурне, так і об'єкто-орієнтовне програмування, має вбудовану підтримку обробки тексту, і володіє вражаючою кількістю модулів, розроблених незалежними постачальниками.

У perl(1), ?perlfaq1(1) та інших документах надано різні визначення мови Perl. З цього ми можемо заключити, що Perl представляє собою різні речі для різних людей, багато з яких однак вважають, що принаймні ця мова заслуговує на те, щоб про неї писати.

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

Для запуску Perl-програми з командного рядка Юнікса, ви маєте виконати:

perl progname.pl

Або додайте наступне, як перший рядок вашого сценарію:

#!/usr/bin/env perl

... і виконайте його, як "/шлях/до/script.pl". Звичайно, файл сценарію має включати дозвіл на виконання, тож не забудьте про "chmod 755 script.pl" (в Юніксі).

Для додаткової інформації з інструкціями щодо інших платформ, таких як Windows чи Mac OS, зверніться до ?perlrun(1).

Огляд синтаксису мови Perl

Сценарій чи програма мовою Perl складається з одного чи більше тверджень. Ці твердження просто записано до файла сценарію в безпосередній спосіб. Немає ніякої потреби у функції main(), або чомусь подібному.

Твердження мови Perl завершує крапка з комою:

print "Hello, world";

Коментарі починаються з гратки, і продовжуються до кінця рядка:

# Це коментар

Пробіли до уваги не беруться:

print
   "Hello, world"
   ;

... за винятком залапкованих ланцюжків:

# Це буде виведено з розривом рядка посередині:
print "Hello
world";

Навколо символьних ланцюжків можуть вживатися як подвійні, так і одинарні лапки:

print "Hello, world";
print 'Hello, world';

Проте, тільки подвійні лапки дозволяють інтерполяцію змінних та спеціальних символів, як знак нового рядка ("\n"), скажімо:

print "Hello, $name\n";     # працює нормально
print 'Hello, $name\n';     # виводить буквально $name\n

Числа не вимагають лапок навколо них:

print 42;

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

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

Більше детальної інформації про синтаксис мови Perl ви знайдете в ?perlsyn(1).

Типи змінних мови Perl

Perl має три основні типи змінних: скаляри, масиви та геші.

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

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

Значення скалярів може складатися з ланцюжка, цілого, або числа з рухомою точкою, і Perl автоматично перетворить їх одне в інше, коли в цьому буде потреба. Таким чином, відпадає потреба попереднього оголошення типів ваших змінних.

Скалярні значення можуть використовуватися в найрізноманітніший спосіб:

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

Існує певна кількість "чарівних" скалярів з назвами, що мають вигляд знаків пунктуації. Ці спеціальні змінні використовуються для різних цілей, і їх описано в ?perlvar(1). Покищо, єдина про яку вам слід знати, це $_, що позначає "змінну без задання". Вона використовується як стандартний аргумент багатьох функцій мови 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 вказує на індекс останнього елемента масиву 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;      # сортує @animals
my @backwards = reverse @numbers;   # обертає послідовність елементів
                                   # у @numbers

Так само, існують кілька спеціальних масивів, як наприклад @ARGV (що містить усі аргументи командного рядка, з якими було викликано ваш сценарій) і @_ (усі аргументи, передані функції). Їх усі описано в ?perlvar(1).

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(1).

Докладніше, скаляри, масиви та геші описані в ?perldata(1).

Складніші типи даних можна створити за допомогою посилань, що дозволяють вам побудувати списки гешів всередині списків гешів.

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

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

   print "Scalars begin with a $variables->{'scalar'}->{'sigil'}\n";

Вичерпну інформацію щодо посилань можна знайти в ?perlreftut(1), ?perllol(1), ?perlref(1) та ?perldsc(1).

Зона дії змінних

У попередніх розділах, у прикладах було використано наступний синтаксис:

my $var = "value";

Оператор "my" насправді необов'язковий; ми могли би обійтися просто:

$var = "value";

Проте, останній приклад створюватиме глобальні змінні у вашій програмі, що вважається поганою практикою програмування. Натомість, "my" дає початок змінним з лексичною (локальною) зоною дії. Зона дії таких змінних обмежується блоком (тобто, набору тверджень, оточених фігурними дужками), в якому їх визначено.

my $a = "foo";
if ($some_condition) {
    my $b = "bar";
    print $a;           # виводить "foo"
    print $b;           # виводить "bar"
}
print $a;               # виводить "foo"
print $b;               # жодного виводу; звернення до $b
                        # поза межами її дії

Конструкції умов та циклів

Perl включає більшість звичайних конструкцій умов та циклів за винятком case/switch (але якщо вона вам дійсно потрібна, то можете встановити модуль Switch з архіву CPAN. Дивіться розділ про модулі нижче для більшої інформації про модулі та CPAN).

Умовою може служити будь-який вираз Perl. Дивіться список операторів з наступного розділу стосовно операторів порівняння та булевої логіки, що зазвичай застосовуються в умовних твердженнях.

if ( умова ) {
    ...
} elsif ( інша умова ) {
    ...
} else {
    ...
}

if :

Існує також заперечна версія if:

unless ( умова ) {
    ...
}

Її надано, як легше-прочитний варіант "if ( !умова )".

Зауважте, що фігурні дужки обов'язкові в Perl, навіть якщо ви маєте тільки один рядок у блоці. Проте, існує один хитрий спосіб зробити ваш блок умови з одного рядка подібнішим на англійську:

# традиційний спосіб
if ($zippy) {
    print "Yow!";
}

# пост-умовний вираз Perl
print "Yow!" if $zippy;
print "We have no bananas" unless $bananas;

while ( condition ) {
    ...
}

while :

Існує також заперечна версія з тих самих міркувань, що й "unless":

until ( condition ) {
    ...
}

Так само "while" може стояти як пост-умова:

print "LA LA LA\n" while 1;    # нескінчений цикл

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

for : Так само як у мові C:

Цей цикл у стилі C рідко коли потрібний в Perl, оскільки остання передбачає більш дружній цикл сканування списків "foreach".

foreach (@array) {
    print "This element is $_\n";
}

foreach :

# вам не конче використовувати стандартну $_ ...
foreach my $key (keys %hash) {
    print "The value of $key is $hash{$key}\n";
}

Для додаткових подробиць щодо циклічних конструкцій (декотрі з яких не були згадані в цьому огляді) дивіться ?perlsyn(1).

Вбудовані оператори та функції

Perl включає широкий спектр вбудованих функцій. Деякі з них ми вже бачили - це "print", "sort" і "reverse". Їхній список наведений напочатку сторінки ?perlfunc(1), і ви легко можете знайти опис певної функції, якщо виконаєте "perldoc -f назва".

Оператори Perl повністю документовано в ?perlop(1), але ось декотрі з найбільш вживаних:

Арифметичні

+ : додавання

- : віднімання

* : множення

/ : ділення

Порівнювання чисел

== : рівність

!= : нерівність

< : менше ніж

: більше ніж

<= : менше чи рівне

= : більше чи рівне

Порівняння ланцюжків

eq : рівність

ne : нерівність

lt : менше ніж

gt : більше ніж

le : менше чи рівне

ge : більше чи рівне

Чому ми маємо окреме порівняння ланцюжків? Тому, що в нас немає спеціальних типів змінних, і Perl має знати, чи сортувати за числовим значенням (коли 99 менше за 100), чи за алфавітним (коли 100 стоїть перед 99).

Булева логіка

&& and : логічне І

|| or : логічне АБО

! not : логічне НЕ (заперечення)

"and", "or" і "not" - це не просто опис операторів у переліку вище, це дійсні оператори. Вони легше читаються ніж аналогічні оператори в стилі C, але мають відмінний пріоритет. Загляніть до ?perlop(1) для додаткових деталей.

Інші оператори

= : присвоєння

. : сполучення ланцюжків

x : повторення (множення) ланцюжків

.. : оператор діапазону

Багато операторів можна поєднати з "=", як показано нижче:

$a += 1; : # тотожно $a = $a + 1

$a -= 1; : # тотожно $a = $a - 1

$a .= "\n"; : # тотожно $a = $a . "\n";

Файли та ввід-вивід

Ви можете відкрити файл для вводу та виводу за допомогою функції "open()". Вона повністю документована в ?perlfunc(1) та ?perlopentut(1), але стисло її можна представити як:

open(INFILE,  "input.txt")   or die "Can't open input.txt: $!";
open(OUTFILE, ">output.txt") or die "Can't open output.txt: $!";
open(LOGFILE, ">>my.log")    or die "Can't open logfile: $!";

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

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

Зчитування цілого файла за раз називається "заковтуванням". Це може стати в пригоді, але й може захопити всю пам'ять. Більшість операцій по обробці тексту можна здійснити, читаючи по одному рядкові за раз, використовуючи циклічні конструкції Perl.

Оператор "<>" найчастіше можна зустріти в циклі "while":

while (<INFILE>) {     # присвоює $_ кожний рядок по черзі
    print "Just read in this line: $_";
}

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

print STDERR "This is your final warning.\n";
print OUTFILE $record;
print LOGFILE $logmessage;

Коли ви закінчили операції над дескриптором файла, то маєте викликати "close()", щоб закрити його (проте, якщо ви забудете, Perl потурбується про це самий):

close INFILE;

Регулярні вирази

Perl підтримує широкий спектр регулярних виразів, що є суб'єктом обширної документації у perlrequick(1), perlretut(1) та решти. Ось стисло:

if (/foo/)       { ... }  # істина, як $_ містить "foo"
if ($a =~ /foo/) { ... }  # істина, якщо $a містить "foo"

Простий збіг :

Оператор порівняння з шаблоном "//" документовано в ?perlop(1). Без задання, він діє відносно $_, або може бути прив'язаний до іншої змінної за допомогою оператора-зв'язки "=~" (також описаного в ?perlop(1)).

s/foo/bar/;           # міняє foo на bar у $_
$a =~ s/foo/bar/;     # міняє foo на bar у $a
$a =~ s/foo/bar/g;    # міняє ВСІ ВИПАДКИ foo на bar у $a

Проста заміна :

Оператор пошуку-заміни "s///" документовано в ?perlop(1).

Складніші регулярні вирази

Ваші пошук не має обмежуватись сталими ланцюжками. Насправді, ваш шаблон може збігтися з усім, що прийде вам в голову, якщо використати складніші регулярні вирази. Їх докладніше описано в perlre(1), але покищо, ось їхній коротенький список:

. : будь-який один символ

\s : пробіловий знак (пробіл, табуляція, знак нового рядка)

\S : не-пробіловий знак

\d : цифра (0-9)

\D : не-цифровий знак

\w : символ, що може належати слову (a-z, A-Z, 0-9, _)

\W : символ, що не може належати слову

[aeiou] : збігається з одним із символів з набору

[^aeiou] : збігається з одним символом крім тих, що вказано в наборі

(foo|bar|baz) : збігається з одним з альтернативних ланцюжків (foo або bar або baz)

^ : початок ланцюжка

$ : кінець ланцюжка

Для вказівки того, з якою кількістю попередньо-вказаних речей ви хочете знайти збіг, можуть використовуватись квантори, де "річчю" може служити або буквальний символ, або один з метасимволів, вказаних вище, або ж група символів та метасимволів у дужках.

  • нуль або більше попереднього

+ : один або більше попереднього

? : нуль або один попереднього

{3} : збігається точно з трьома попередньо-вказаними речами

{3,6} : збігається з від трьох до шести попередньо-вказаних речей

{3,} : збігається з трьома або більше попередньо-вказаних речей

Пара коротких прикладів:

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

# Цей цикл читає із STDIN і виводить не-порожні рядки:
while (<>) {
    next if /^$/;
    print;
}

Дужки для захоплення

Окрім гуртування, дужки служать також для іншої цілі. Їх можна використовувати для захоплення частин збігів з регулярним виразом для пізнішого використання. Ці захоплені частини буде збережено в $1, $2 і так далі.

  1. дешевий та неохайний спосіб розбити ел. адресу на частини

    if ($email =~ /([^@]+)@(.+)/) { print "Username is $1\n"; print "Hostname is $2\n"; }

Інші властивості регулярних виразів

Регулярні вирази Perl також підтримують зворотні звернення, попередній пошук та інші, складніші речі. Ви можете дізнатися про них з perlrequick(1), perlretut(1) і perlre(1).

Написання підпрограм

Скласти власну підпрограму (функцію) в Perl досить легко:

sub log {
    my $logmessage = shift;
    print LOGFILE $logmessage;
}

Що це за "shift", спитаєте ви. Гаразд, пояснимо: аргументи підпрограми, усі зберігаються у спеціальному масиві @ (дивіться ?perlvar(1), щоб дізнатися більше). Аргументом без задання функції "shift" є саме @. Таким чином, "my $logmessage = shift;" зміщує перший елемент зі списку аргументів, і присвоює його $logmessage.

Можна й по-іншому маніпулювати @_:

my ($logmessage, $priority) = @_;    # загальноприйнятий спосіб
my $logmessage = $_[0];              # незвичний та потворний спосіб

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

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

Для додаткової інформації про написання підпрограм, дивіться ?perlsub(1).

Об'єкно-орієнтований Perl

Об'єкно-орієнтований Perl - доволі простий, і втілено за допомогою посилань, які знають яким типом об'єкту вони є, основуючись на понятті пакету мови Perl. Проте, об'єктно-орієнтований Perl аж ніяк не вписується в межі цього документа. Читайте ?perlboot(1), ?perltoot(1), ?perltooc(1) і ?perlobj(1).

Як початківець програмування мовою Perl, ви найчастіше стикатиметесь з об'єкто-орієнтовним Perl при використанні сторонніх модулів, про які йтиметься далі.

Використання модулів Perl

Модулі Perl забезпечують широким діапазоном можливостей, що запобігають потреби винаходити колесо, і їх можна завантажити з архіву CPAN ( http://www.cpan.org/ ). Певна кількість найпопулярніших модулів включено в самий дистрибутив Perl.

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

Щоб дізнатися, як встановити модулі, завантажені зі CPAN, прочитайте ?perlmodinstall(1).

Для інформації щодо використання якогось модуля, скористайтеся з "perldoc Модуль::Назва". Типово, вам потрібно додати рядок "use Модуль::Назва", що надасть вам доступ до експортованих функцій об'єктно-орієнтованого інтерфейсу модуля.

Сторінка ?perlfaq(1) містить питання та відповіді, пов'язані з багатьма поширеними завданнями, і радить, яким модулем CPAN краще скористатися для цього.

Сторінка ?perlmod(1) містить загальний опис модулів Perl. ?perlmodlib(1) надає перелік модулів, що надійшли з вашою інсталяцією Perl.

Якщо ви маєте бажання написати власний модуль Perl, тоді ?perlnewmod(1) забезпечить вас хорошими порадами.

АВТОР

Kirrily "Skud" Robert skud@cpan.org