Перейти к основному содержимому

Первая программа на Perl

Разработчику

Черновик статьи. Ниже — пошаговый маршрут: установка, strict/warnings, скаляры, массивы, хеши, файлы, regex, cpanm и тесты.

ШагТемаЗачем
1Установка и perl -vСреда готова
2Hello World + strictБезопасный старт
3Скаляры и строки$var, интерполяция
4Массивы и хеши@arr, %hash
5Чтение файла<> и ARGV
6Regex=~, замена
7cpanm и модулиCPAN
8prove и тестыTAP

Контекст — история, о разделе. Shell-альтернатива — Bash.


Шаг 1 — подготовка

Проверка установки:

perl -v
ПлатформаРекомендация
LinuxСистемный perl или perlbrew
macOSСистемный + brew install perl при необходимости
WindowsStrawberry 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Редактировать файл на месте
-aAutosplit как 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Нет myuse strict, объявить переменную
BarewordОпечатка или строка без кавычекКавычки или => в hash
Argument isn't arrayScalar вместо listПроверить контекст
Module not foundНет cpanm installcpanm Module::Name
Permission denied shebangНет +xchmod +x или perl file.pl

Что дополнится в полной версии

  1. Moo — минимальный OO класс.
  2. Path::Tiny — современная работа с путями.
  3. Plack — PSGI hello world.
  4. perlbrew в CI.
  5. Сравнение с 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Нет в @INCcpanm, use lib
Пустой @ARGVЗапуск без аргументовПроверить usage

Связь с разделом

СтатьяТема
ИсторияLarry Wall, CPAN
О разделеКонтексты, regex preview
Bash introPipeline 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.


Упражнения (дополнение)

  1. Rewrite log filter in process.pl with Path::Tiny.
  2. Add Moo class with two attributes and method.
  3. Benchmark perl -pe vs reading file in script.
  4. Export JSON from hash with pretty print.
  5. Run perlcritic on 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