НАЗВА
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 і так далі.
дешевий та неохайний спосіб розбити ел. адресу на частини
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