Первая программа на Perl
Черновик статьи. Ниже — пошаговый маршрут: установка, strict/warnings, скаляры, массивы, хеши, файлы, regex, cpanm и тесты.
| Шаг | Тема | Зачем |
|---|---|---|
| 1 | Установка и perl -v | Среда готова |
| 2 | Hello World + strict | Безопасный старт |
| 3 | Скаляры и строки | $var, интерполяция |
| 4 | Массивы и хеши | @arr, %hash |
| 5 | Чтение файла | <> и ARGV |
| 6 | Regex | =~, замена |
| 7 | cpanm и модули | CPAN |
| 8 | prove и тесты | TAP |
Контекст — история, о разделе. Shell-альтернатива — Bash.
Шаг 1 — подготовка
Проверка установки:
perl -v
| Платформа | Рекомендация |
|---|---|
| Linux | Системный perl или perlbrew |
| macOS | Системный + brew install perl при необходимости |
| Windows | Strawberry Perl или WSL |
Версия 5.36+ или 5.40 — современные фичи (signatures в experimental). use v5.40; в начале файла фиксирует минимум.
Шаг 2 — Hello World
hello.pl:
#!/usr/bin/env perl
use v5.40;
use strict;
use warnings;
print "Привет, мир!\n";
Запуск:
chmod +x hello.pl # Unix
./hello.pl
# или
perl hello.pl
Разбор:
use strict— объявлять переменные черезmy(илиourв пакетах).use warnings— предупреждения о подозрительных конструкциях.- Shebang
#!/usr/bin/env perl— запуск как исполняемый файл. print— вывод без автоматического\n.
С аргументом командной строки:
my $name = $ARGV[0] // 'мир';
print "Привет, $name!\n";
perl hello.pl Анна
Шаг 3 — скаляры и строки
my $count = 42;
my $title = 'Perl';
my $greeting = "Привет, $title!"; # интерполяция в двойных кавычках
my $literal = 'Привет, $title!'; # буквально $title
| Сигил | Тип | Пример |
|---|---|---|
$ | scalar | $x |
@ | array | @items |
% | hash | %user |
Конкатенация: $a . $b. Длина строки: length $s.
Шаг 4 — массивы и хеши
my @colors = qw(red green blue);
my $second = $colors[1]; # green
my $len = scalar @colors; # 3
push @colors, 'yellow';
my %user = (
name => 'Anna',
role => 'admin',
);
print $user{name}; # Anna
exists $user{email} or print "no email\n";
Срезы: @colors[0, 2]. Ключи хеша: keys %user.
Шаг 5 — подпрограммы
sub greet {
my ($name) = @_;
return "Привет, $name!";
}
print greet('мир'), "\n";
@_ — массив аргументов. В strict всегда my ($a, $b) = @_.
Шаг 6 — чтение файла
Весь файл в память
open my $fh, '<', 'data.txt' or die "Cannot open: $!";
my @lines = <$fh>;
close $fh;
chomp @lines; # убрать \n
Diamond operator и @ARGV
while (<>) {
chomp;
print "$.: $_\n";
}
perl script.pl file1.txt file2.txt
# или stdin:
cat file.txt | perl script.pl
Подсчёт слов (учебный пример)
wordcount.pl:
#!/usr/bin/env perl
use v5.40;
use strict;
use warnings;
my $total = 0;
while (<>) {
$total += scalar split /\s+/;
}
print "Слов: $total\n";
Шаг 7 — регулярные выражения
my $line = '2024-01-15 ERROR disk full';
if ($line =~ /ERROR/) {
print "Найдена ошибка\n";
}
if ($line =~ /^(\d{4}-\d{2}-\d{2})\s+(\w+)\s+(.*)$/) {
my ($date, $level, $msg) = ($1, $2, $3);
print "$date [$level] $msg\n";
}
# замена
$line =~ s/ERROR/WARN/;
| Модификатор | Смысл |
|---|---|
i | без учёта регистра |
m | ^ и $ по строкам |
g | все совпадения при replace |
x | пробелы в паттерне для читаемости |
Однострочник filter:
perl -pe 's/ERROR/WARN/g' app.log
Шаг 8 — cpanm и модули
Установка cpanminus:
# Linux/macOS
curl -L https://cpanmin.us | perl - App::cpanminus
cpanm --version
Установка модуля:
cpanm JSON::PP
cpanm Path::Tiny
Пример с JSON:
use v5.40;
use strict;
use warnings;
use JSON::PP qw(encode_json decode_json);
my $data = { message => 'Hello', count => 2 };
my $json = encode_json($data);
print "$json\n";
my $back = decode_json($json);
print $back->{message}, "\n";
Зависимости проекта — cpanfile + cpanm --installdeps . (аналог requirements.txt). Теория пакетов — манифесты.
Шаг 9 — однострочники
perl -e 'print "2 + 2 = ", 2+2, "\n"'
# построчная обработка
perl -ne 'print if /ERROR/' error.log
# in-place edit (бэкап .bak)
perl -i.bak -pe 's/foo/bar/' config.txt
| Флаг | Действие |
|---|---|
-e | Код в командной строке |
-n | Читать строки, не печатать по умолчанию |
-p | Как -n, но печатать каждую строку |
-i | Редактировать файл на месте |
-a | Autosplit как awk |
Шаг 10 — тесты с prove
Makefile.PL или только t/:
# t/greet.t
use v5.40;
use strict;
use warnings;
use Test::More tests => 2;
sub greet {
my ($name) = @_;
return "Привет, $name!";
}
is(greet('мир'), 'Привет, мир!', 'greet мир');
is(greet('Perl'), 'Привет, Perl!', 'greet Perl');
cpanm Test::More
prove -v t/greet.t
prove запускает TAP-тесты — стандарт Perl-сообщества.
Типичные ошибки
| Симптом | Причина | Решение |
|---|---|---|
| Global symbol | Нет my | use strict, объявить переменную |
| Bareword | Опечатка или строка без кавычек | Кавычки или => в hash |
| Argument isn't array | Scalar вместо list | Проверить контекст |
| Module not found | Нет cpanm install | cpanm Module::Name |
| Permission denied shebang | Нет +x | chmod +x или perl file.pl |
Что дополнится в полной версии
- Moo — минимальный OO класс.
- Path::Tiny — современная работа с путями.
- Plack — PSGI hello world.
- perlbrew в CI.
- Сравнение с Python
pathlibиreдля миграции скриптов.
Напишите logfilter.pl: читает stdin, печатает только строки с ERROR, считает их число в конце. Запустите на тестовом файле и через cat log | perl logfilter.pl.
См. также: о разделе · история · Пакетные менеджеры.
Шаг 14 — hash slice и exists
my %user = (name => 'Anna', role => 'admin');
say $user{name};
say exists $user{email} ? 'yes' : 'no';
my @names = @user{qw(name role)};
Шаг 15 — references preview
my $x = 42;
my $ref = \$x;
$$ref = 100;
say $x; # 100
References — основа для complex data structures; подробнее в статье 2.
Шаг 16 — here document
my $html = <<"HTML";
<html><body><p>Hello</p></body></html>
HTML
Удобно для шаблонов в legacy CGI.
Шаг 17 — @ARGV и exit codes
use v5.36;
my ($file) = @ARGV or die "usage: $0 FILE\n";
say "reading $file";
exit 0;
exit 1 при ошибке — convention для shell scripts и cron.
Шаг 18 — say и $"
local $" = ', ';
my @items = qw(a b c);
say "items: @items"; # items: a, b, c
$" — separator при интерполяции массива в строку.
Шаг 19 — filehandle и die
open my $fh, '<', $file or die "cannot open $file: $!";
while (my $line = <$fh>) {
chomp $line;
say $line if $line =~ /ERROR/;
}
close $fh;
Трёхаргументный open — best practice вместо open FILE, $file.
Шаг 20 — use FindBin для относительных путей
use FindBin;
use lib "$FindBin::Bin/lib";
use MyModule;
Скрипт находит свою директорию — полезно для portable deploy без PERL5LIB.
Типичные ошибки первого запуска
| Ошибка | Причина | Решение |
|---|---|---|
Global symbol requires explicit package | Нет use strict | Добавить strict/warnings |
Bareword found | Опечатка или не quoted string | Проверить $var vs @var |
Can't locate Module.pm | Нет в @INC | cpanm, use lib |
Пустой @ARGV | Запуск без аргументов | Проверить usage |
Связь с разделом
| Статья | Тема |
|---|---|
| История | Larry Wall, CPAN |
| О разделе | Контексты, regex preview |
| Bash intro | Pipeline glue |
Чек-лист: первая программа освоена
-
use strict; use warnings; use v5.36; - Hello World через
say - Однострочник
-neили-peна тестовом файле - Скрипт с
@ARGVиexit - Прочитан CPAN overview
Дальше: regex и файлы (статья 3, когда появится) · история.
Шаг 21 — Path::Tiny (модуль)
cpanm Path::Tiny
use v5.36;
use strict;
use warnings;
use Path::Tiny qw(path);
my $content = path('data.txt')->slurp_utf8;
say $content;
Современная альтернатива raw open — см. конфигурации и данные.
Шаг 22 — Moo (минимальное ОО)
use v5.36;
use strict;
use warnings;
use Moo;
package User {
use Moo;
has 'name' => (is => 'ro', required => 1);
sub greet ($self) { return "Hi, " . $self->name }
}
my $u = User->new(name => 'Anna');
say $u->greet;
FAQ (дополнение)
Strawberry vs system Perl? Windows — Strawberry; macOS — Homebrew perl для свежей версии.
-T taint? Deprecated; explicit validation вместо taint mode.
say vs print? say adds newline; needs feature or v5.36.
Unicode file? use utf8;, binmode STDOUT, ':encoding(UTF-8)';
prove vs perl t.t? prove aggregates test results.
Carton? Lock CPAN deps per project — like bundler.
Next article? Regex deep dive when published in section.
Упражнения (дополнение)
- Rewrite log filter in
process.plwith Path::Tiny. - Add Moo class with two attributes and method.
- Benchmark
perl -pevs reading file in script. - Export JSON from hash with pretty print.
- Run
perlcriticon your script severity 3+.
Шаги 1–22 покрывают strict, IO, regex, one-liners, cpanm, tests. Дальше — CPAN modules и legacy reading по истории.
Шаг 23 — JSON с JSON::MaybeXS
cpanm JSON::MaybeXS
use v5.36;
use strict;
use warnings;
use JSON::MaybeXS qw(encode_json decode_json);
my $json = encode_json({ name => 'Anna', role => 'admin' });
my $data = decode_json($json);
say $data->{name};
Шаг 24 — prove для тестов
cpanm Test::More
prove -v t/basic.t
prove агрегирует результаты .t файлов — стандарт CPAN distributions.
Чек-лист финальный
- strict/warnings/v5.36 в каждом скрипте
- cpanm установил минимум два модуля
- Однострочник на реальном log-файле
- Тест через prove или
perl t/*.t