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

Perl
Perl

Что из себя представляет Perl?

Perl — это скриптовый язык (как Bash или Python), разработанный ещё в 1987 году Лэри Волом. Perl — динамически типизированный. По синтаксису код на нём выглядит как что‑то между Python, C, и чем‑то своим, при этом одним из его девизов является — «Здесь больше одного способа это сделать», что отражается в исключительной гибкости языка.

Пример вывода “Hello, World!”:

my $var = "World"; # Инициализация локальной переменной $var

print ("Hello, $var!\n");       # Стандартный пример вывода "Hello, World!"
print "Hello, $var!\n";         # Без скобочек
print "Hello, ", $var, "!\n";   # В виде листа аргументов, разделённых запятой
print "Hello, " . $var . "!\n"; # В виде строки, которая соединяется в одну точками
printf "Hello, %s!\n", $var;    # printf
say "Hello, $var!"; # say - тоже самое, что и print, только с переносом строки на конце
                    # Есть в Perl 5.10 и позднее

Пример отсчёта от 10 до 1:

# Стандартный для C for loop
for (my $i = 10; $i > 0; --$i) {
    say $i;
}

# foreach по перевёрнутому массиву от 1 до 10
foreach my $i (reverse 1..10) {
    say $i;
}

# Никакой разницы между foreach и for нет
for my $i (reverse 1..10) {
    say $i;
}

# Запись и вывод из дефолтного значения $_
for (reverse 1..10) {
    # То же самое как если бы мы записали
    # for my $_ (reverse 1..10)
    say $_;
}

# В одну строчку
say $_ for reverse 1..10;

Кроссплатформенность и простота работы с системой.

Так как Perl изначально создавался как скриптовый язык общего назначения для Unix, на многих Unix системах он стоит по умолчанию. Можете сами проверить есть ли он у вас whereis perl.

Конечно для пользователей прекрасной и неповторимой Windows не всё так просто, но в отличие от Bash, не нужны никакие танцы с бубном для эмуляции Linux и достаточно просто cкачать интерпретатор Perl.

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

# cat в одну строку, который принимает в себя любое число файлов и выводит их содержание.
# Даже точка с запятой на конце не нужны потому, что в конце блока её можно не ставить.

print <> # Алмазный оператор <> - это оператор ввода пользовательского выбора

# Этот оператор работает следующим образом: если пользователь передал в программу файлы,
# то он возвращает их содержание, если нет, то принимает ввод с консоли до тех пор пока
# пользователь не вернёт end-of-file код (Сtrl-D) и возвращает введённое
print sort <> # Сортирует все строки файла и выводит их в консоль
# Аналог 'nl -b a' который нумерует все строки файла и выводит их в консоль

printf "%6d  $_", $. while <> # $. возвращает номер строки
Что-то подобное алмазному оператору <> на языке Perl можно написатьследующим образом:
# Сабрутина (то же самое что и функция в других языках) subr
sub subr {
    my $ret; # Инициализация локальной переменной $ret

    # Если массив входных параметров программы, @ARGV, пустой, то принимать
    # ввод с консоли и построчно объединять его с переменной $ret
    if (!@ARGV)
    {
        while (my $line = <STDIN>) {
            $ret .= $line;
        }
    }

    # Если в программу передавались параметры, то поочереди открывать каждый
    # файл в режиме чтения и построчно записывать его содержание в $ret
    else
    {
        foreach my $ARG (@ARGV)
        {
            open my $fd, "<", $ARG;

            while (my $line = <$fd>) {
                $ret .= $line;
            }
        }
    }
    return $ret;
}

# Вызов функции
print &subr

а

Можете сами попробовать создать main.pl вставить туда код и запустить:

perl main.pl PATH_TO_FILE

В Perl также просто можно вызывать системные комманды и обрабатывать их вывод, что в сочетании с непревзойдённой работой с текстом (о которой будет следующий параграф) может сильно упростить жизнь.

# Оператор `` исполняет команду и возвращает результат её вывода, когда она завершится
my $ping = `ping google.com -w 2`;
print $ping
# -| открывает программу на чтение вывода
open( my $ping, '-|', 'ping google.com -w 2' );

# Будет выводить в консоль результат вывода команды по ходу её выполнения
while my $line (<$ping>) {
    print $line
}

Таким образом я считаю, что Perl куда проще, мощнее и гибче чем Bash, но конечно наверное болшинство знает Bash, да и его использование более распространено. Но тем не менее, если есть возможность писать скрипт на Perl, вместо того, чтобы делать это на Bash, то почему бы и нет, особенно если вы хотите, чтобы этот скрипт работал не только на Unix, но и на Windows, хотя возможно для такого бы также хорошо подошёл Python. Всё зависит от ваших целей, желаний и ограничений.

Работа с текстом

Работа с текстом - это пожалуй самая сильная сторона Perl и главный фактор послуживший его популярности, ну и причина почему я сам начал его изучать. Из‑за глубокой интеграции с regexp и тем как страшно и непонятно код на regexp может выглядеть, иногда можно услышать, что о Perl отзываются как «write only language», но это глубоко не так и даже наоборот и сейчас я докажу это вам на своём примере.

Так вот, когда я делал 3D игру с raylib, у меня появилась потребность в использовании 3D редактора карт и я нашёл TrenchBroom. Для энтити, которых можно добавлять на карту TrenchBroom использует формат .FGD, а этот формат очень специфичный, пеприятный и с ним довольно таки неудобно работать, ну и мне в любом случае прийдётся этих энтити прописывать на C/C++, поэтому зачем вообще к этому формату прикасаться? Вместо этого можно написать программу, которая принимает в себя C/C++ код в виде классов/структур и переводит его в .FGD.

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

#ifndef EXAMPLE_H
#define EXAMPLE_H

// Example class
struct Example {
    const char* name;
    int hp; // Character's health
    void spawn();
    // Substracts damage from hp
    void takeDamage(int damage);
};

struct Example2 {
    int ammount = 0; // Ammount of stuff
    Example2();
    // Returns true if ammount is even
    bool isEven();
};

#endif //EXAMPLE_H

Вот в это:

@PointClass size(-16 -16 -32, 16 16 32) = Example : "Example class"
[
    name(string): :  : ""
    hp(integer): :  : "Character's health"
]
@PointClass size(-16 -16 -32, 16 16 32) = Example2 : ""
[
    ammount(integer): : 0 : "Ammount of stuff"
]

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

  1. Структуры типа // COMMENT\n struct NAME {...}; переводятся в .FGD классы формата @PointClass size(-16 -16 -32, 16 16 32) = NAME : "COMMENT" [...] при том, что комментарии опциональны.

  2. Поля структуры типа TYPE NAME = DEFINITION; // COMMENT переводятся в поля .FGD класса формата NAME(TYPE): : DEFINITION : "COMMENT", при этом определения полей и комментарии опциональны.

  3. Типы int и const char* переводятся в integer и string.

  4. Все лишние методы класса, лишние комментарии, макросы и инклюды полностью удаляются.

Перед тем как перейти к решению на Perl давайте посмотрим как можно добится подобного результата на другом языке. Тут я уточню, что кроме C/C++ больше ничего то толком и не знаю, поэтому для меня вариантов не много. Очевидно, что для текущей задачи нужно использовать регулярные выражения, а то в противном случае решение получится чрезмерно большим, некрасивым и сложным.

regex.h простой и подойдёт для валидации небольшого набора данных, к примеру IP адрес, пароль, имя пользавателя и тп., но если нужно что-то побольше, то тут его функционала уже начинает не хватать, и получайются очень длинные однострочные write only регекспы. std::regex уже получше, но с ним всё та же проблема.

Есть PCRE2 (Perl Compatable Regular Expressions), который имеет очень мощный функционал, но который требует вызова функций с кучей параметров, что создаёт много шума из-за чего его труднее воспринимать, и для маленькой програмки с одной единственной целью это уже перебор.

Пример кода из их репозитория
/* Set PCRE2_CODE_UNIT_WIDTH to indicate we will use 8-bit input. */
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>

#include <string.h> /* for strlen */
#include <stdio.h>  /* for printf */

int main(int argc, char* argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <pattern> <subject>\n", argv[0]);
        return 1;
    }

    const char *pattern = argv[1];
    const char *subject = argv[2];

    /* Compile the pattern. */
    int error_number;
    PCRE2_SIZE error_offset;
    pcre2_code *re = pcre2_compile(
        pattern,               /* the pattern */
        PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */
        0,                     /* default options */
        &error_number,         /* for error number */
        &error_offset,         /* for error offset */
        NULL);                 /* use default compile context */
    if (re == NULL) {
        fprintf(stderr, "Invalid pattern: %s\n", pattern);
        return 1;
    }

    /* Match the pattern against the subject text. */
    pcre2_match_data *match_data =
        pcre2_match_data_create_from_pattern(re, NULL);
    int rc = pcre2_match(
        re,                   /* the compiled pattern */
        subject,              /* the subject text */
        strlen(subject),      /* the length of the subject */
        0,                    /* start at offset 0 in the subject */
        0,                    /* default options */
        match_data,           /* block for storing the result */
        NULL);                /* use default match context */

    /* Print the match result. */
    if (rc == PCRE2_ERROR_NOMATCH) {
        printf("No match\n");
    } else if (rc < 0) {
        fprintf(stderr, "Matching error\n");
    } else {
        PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
        printf("Found match: '%.*s'\n", (int)(ovector[1] - ovector[0]),
               subject + ovector[0]);
    }

    pcre2_match_data_free(match_data);   /* Free resources */
    pcre2_code_free(re);
    return 0;
}

А вот boost/regex.hpp - это пожалуй самый лучший вариант из всех, тк совмещает в себе простоту и мощь регекспа Пёрла, никак при этом не давя на глаза.

Пример того как первый шаг конвертации мог бы выглядеть с boost/regex.hpp
#include <boost/regex.hpp>
#include <fstream>
#include <iterator>
#include <string>

int main(int argc, char **argv)
{
    std::ifstream ifs(argv[1], std::ios::binary);
    std::string source((std::istreambuf_iterator<char>(ifs))
                      , std::istreambuf_iterator<char>());

    const boost::regex re(R"((?xs)
    (?: \s* //\s* (?<struct_comment>[^\n]*) )?

    (?<struct>
        \s* struct\s+ (?<struct_name>\w+\d?)\s* \{
            (?<struct_content>.*?)
        \};
    )
    )", boost::regex::perl);

    const std::string repl = R"(
@PointClass size(-16 -16 -32, 16 16 32) = $+{struct_name} : "$+{struct_comment}"
[
    $+{struct_content}
]
)";

    source = boost::regex_replace( source, re, repl
                                 , boost::match_default
                                 | boost::format_perl );

    std::ofstream ofs(argv[2], std::ios::binary);
    ofs << source;
    return 0;
}

Результат конвертации:

#ifndef EXAMPLE_H
#define EXAMPLE_H

@PointClass size(-16 -16 -32, 16 16 32) = Example : "Example class"
[

    const char* name;
    int hp; // Character's health
    void spawn();
    // Substracts damage from hp
    void takeDamage(int damage);

]

@PointClass size(-16 -16 -32, 16 16 32) = Example2 : ""
[

    int ammount = 0; // Ammount of stuff
    Example2();
    // Returns true if ammount is even
    bool isEven();

]


#endif //EXAMPLE_H

У питона есть модуль re тоже способный на написание понятного regex кода:

charref = re.compile(r"""
 &[#]                # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
""", re.VERBOSE)

Ну а как бы этот конвертер выглядел на самом Perl? Как-то так, но если вкратце и с пояснениями, то так:

#!/usr/bin/env perl

# Используем самую последнюю версию Perl она по деволту включает strict и warnings
use v5.42;
# Для корректной работы untf8
use utf8;
binmode STDOUT, ':encoding(UTF-8)';
binmode STDIN, ':encoding(UTF-8)';

# Первый аргумент - C стркутура, второй - путь куда будет экспортирован конвертированный файл
my $source = $ARGV[0];
my $dest = $ARGV[1];

# Чтение открытого файла
open (my $source_file, '<', $source)
    or die "Could not open source file: $!\n";

# Соединяем все строки в одну
my $source_code = join '', <$source_file>;


# Заменяем структуру на .FGD
$source_code =~ s{
# Необязательный комментарий к структуре
(?: ^\s* //\s* (?<struct_comment>[^\n]*) )?

# Блок структуры
(?<struct>
    \s* struct\s+ (?<struct_name>\w+\d?)\s* \{
        (?<struct_content>.*?)
    \};
)

}{\@PointClass size(-16 -16 -32, 16 16 32) = $+{struct_name} : "$+{struct_comment}"
[
    $+{struct_content}
]

}mgxs; # m для того, чтобы $^\R были для каждой строки, а не всего файла
       # g для замены всех совпадений, а не только первого
       # x для того, чтобы regexp игнорировал пробельные символы и всё можно
       #   было читаемо разместить
       # s для того, чтобы любой символ . также принимал в себя \n

# Замена полей структуры на поля .FGD класса
$source_code =~ s{
# Парс типа, имени, определения и комментария поля
\s* (?<variable_type>[\w\s*::<>]+?)\s+
    (?<var_name>\w+)
    (?:\s* =\s* (?<default_value>\w+?))?;
    (?:\s* //\s* (?<var_comment>[^\n]+))?
}{
    $+{var_name}($+{variable_type}): : $+{default_value} : "$+{var_comment}"
}mgxs;

# Удаление всех лишних строк
$source_code =~ s{
^\s*
# Строки начинающиеся с #, //, заканчивающиеся с ; с возможным комментарием
# и просто пустые строки
( \#.+ | //.*? | .*?; (\s*//.*)? | )
\R
}{}mgx;

# Переименование типов данных
$source_code =~ s/\((const )?int\)/(integer)/g;
$source_code =~ s/\((const )?char\*\)/(string)/g;

# Запись файла
open (my $dest_file, '>', $dest)
    or die "Could not create dest file: $!\n";

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

Пользовательские модули CPAN

Для Perl написано очень много пользовательских модулей для самых разных задач (прямо как и для Python), но пожалуй самыми полезными из них являются Getopt::Long и Pod::Usage, которые позволяют очень просто передавать параметры в программу и документировать код. Многие стандартные модули идут сразу вместе с Perl (включая те, про которые я только что рассказал), а те, что и не идут можно достаточно просто скачать. Для этого я рекомендую использовать cpanm, тогда процесс установки любого модуля упрощается до sudo cpanm MODULE. На NixOS я просто пишу такой простой шелл конфиг:

shell.nix
{ pkgs ? import <nixpkgs>{}}:

let
  perll = with pkgs; [
    perl
    perlnavigator
  ];

  # А здесь сами модули
  perl_modules = with pkgs.perl5Packages; [
  ];

in
pkgs.mkShell {
  nativeBuildInputs = perll ++ perl_modules;
}

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

#!/usr/bin/env perl

use v5.42;
use utf8;
binmode STDOUT, ':encoding(UTF-8)';
binmode STDIN, ':encoding(UTF-8)';
# Подключаем пользовательске модули
use Furl;
use Getopt::Long;
use Pod::Usage;

# Задаём дефолтные значения
my $help = 0;
my $proxy_list =
'https://cdn.jsdelivr.net/gh/proxifly/free-proxy-list@main/proxies/all/data.txt';
my $timeout = 1;

# Обрабатываем входные параметры
GetOptions( 'help|?' => \$help
          , 'link-to-proxy|p=s' => \$proxy_list
          , 'timeout|t=i' => \$timeout);
pod2usage(1) if $help;
pod2usage(2) unless $ARGV[0];

# Открываем сайт со списком прокси и записываем все прокси в массив @proxy_list
my $furl = Furl->new(timeout => 5);
my @proxy_list = split( /\n/, $furl->get($proxy_list)->content );

# Записываем аргументы переданные в программу в список cайтов, которые мы будем
# пинговать
my @link_list = @ARGV;


my %proxy_hash;
my $counter = @proxy_list;
foreach my $proxy (@proxy_list)
{
    say $counter--, '..'; # Отcчёт того сколько прокси осталось

    foreach my $link (@link_list)
    {
        # Делаем curl запрос
        open my $fh, '-|',
        "curl -s -x GET -o /dev/null --write-out '\%{exitcode} \%{time_total}' --proxy $proxy -m $timeout $link";

        while (my $line = <$fh>)
        {
            # Проверяем что запрос удался и если да, то выводим результат и
            # записываем его в %proxy_hash
            if ($line =~ /^(?<exit_code>\d+) (?<time>.+)/
            and $+{exit_code} == 0 && $+{time} < $timeout)
            {
                say "$+{time} - $proxy";
                $proxy_hash{$proxy} .= $+{time};
            }
        }
    }
}

# Сортируем все прокси по времени и выводим
foreach (sort {$proxy_hash{$a} <=> $proxy_hash{$b}} keys %proxy_hash) {
    say "$proxy_hash{$_} - $_";
}

# perlpod документация
__END__

=head1 SYNOPSIS

main.pl [options...] <urls...>

=head1 OPTIONS

=over 4

=item B<-h, --help>

Prints this message.

=item B<-p, --link-to-proxy> <url>

Link to a site from that to fetch proxy server links.

Default is: https://cdn.jsdelivr.net/gh/proxifly/free-proxy-list@main/proxies/all/data.txt

=item B<-t, --timeout> <seconds>

Max time to wait for a responce before switching to next proxy.

Default is: 1

=back

=cut
Результат работы программы
% ./main.pl
Usage:
    main.pl [options...] <urls...>


% ./main.pl -h
Usage:
    main.pl [options...] <urls...>

Options:
    -h, --help
        Prints this message.

    -p, --link-to-proxy <url>
        Link to a site from that to fetch proxy server links.

        Default is:
        https://cdn.jsdelivr.net/gh/proxifly/free-proxy-list@main/proxies/al
        l/data.txt

    -t, --timeout <seconds>
        Max time to wait for a responce before switching to next proxy.

        Default is: 1


% ./main.pl -t 2 google.com
3408..
1.499812 - socks5://72.49.49.11:31034
3407..
3406..
1.611254 - socks5://69.61.200.104:36181
3405..
3404..
3403..
3402..
3401..
3400..
3399..
^C

Ресурсы для дальнейшего изучения

Если вас заинтересовал Perl, то я рекомендую следующие ресурсы к ознакомлению:

  • perldoc/perlintro - краткое введение в Perl и его возможности.

  • perldoc/perl - документация всего Perl.

  • perldoc/perlvar - $_, $., $!, $$ и тд.

  • perldoc/perlre - о регулярках в Perl.

  • PerlTutorial - простые туториалы для начинающих.

  • pelmaven/perl-tutuorial - блог на разные темы, знать которые может пригодиться.

  • metacpan - сайт с пользовательскими модулями для Perl.

Ну а также крайне особо сильно настоятельно рекомендую прочитать Learning Perl 8th Edition, очень хорошая книга 2021-ого года. Если к тому времени, как вы читаете эту статью выйдет новое издание — читайте его. Удачи!

Выводы

В процессе написания этой статьи я понял, что уникальность и особенность языка Perl, к сожалению не делает его незаменимым инструментом, а очень даже заменимым (заменимым на Python). У языка есть свои особенности, он по-своему необычен, интересен и крут, но есть ли сейчас много толка в его изучении? Ну насколько много, это вопрос хороший, но толк в этом для меня точно был.

Комментарии (92)


  1. oliva80
    20.04.2026 20:56

    "Забытый” — это сильное преувеличение. Скорее, Perl перешёл из мейнстрима в нишевый инструмент для конкретных задач. Если 15 лет назад для задач на HP-UX на PA-RISC ты выбрал Perl и теперь у тебя куча легаси, он всё ещё твой лучший друг! Без проблем перенесёшь на любую современную платформу, сэкономив немало сил и средств.

    Куча критической инфраструктуры (банки, заводы, энергетика) построена на этом "железе". Можно переписать на Python, но это X-Y месяцев работы команды, тесты, риски. А старый Perl-скрипт просто работает. И теперь твоё мудрое, принятое 15 лет назад решение, экономит компании миллионы.


    1. DMGarikk
      20.04.2026 20:56

      Он экономит миллионы, до тех пор как надо брать новых людей на поддержку этого кода..а их все меньше и меньше,

      Хотя ИИ теперь есть


      1. AnotherAnkor
        20.04.2026 20:56

        Перл очень простой язык. Если человек не способен его изучить и писать на нём, у меня возникает непонимание как вообще в ит попал такой человек. Он сильно проще той же жабы.


        1. unreal_undead2
          20.04.2026 20:56

          В том то и дело, что писать просто. Читать чужой код уже сложнее )


        1. DMGarikk
          20.04.2026 20:56

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

          бейсик простой язык и паскаль, слабо вам прям сейчас взять проект на полмиллиона строк кода на паскале (не object) и поддерживать? язык то простой! проще жабы!


          1. rivo
            20.04.2026 20:56

            Паскаль, а еще лучше Дельфя, вполне простой язык и достаточно безопасный. Вот если бы предлложили 0.5м строк легаси С++ я бы лично напрягся и хорошенько подумал.


            1. DMGarikk
              20.04.2026 20:56

              Паскаль, а еще лучше Дельфя

              ага, конечно лучше, ктобы сомневался, но Делфя сложнее для освоения, давайте уж Паскаль будем рассматривать, он же проще ;)

              и именно Паскаль, не object, очень простой язык, кто угодно выучит, давайте полмиллиона строк процедурного кода и вперед

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

              p.s. я знаю что в перле есть ООП, я про другое сейчас


              1. rivo
                20.04.2026 20:56

                Даже незнаю какой версией пользовался TurboPascal. ООП добавили примерно в 1989 году, но я тогда его не понимал совсем. Писла в школе для друзей утилиты DOSовские для работы с дисками и всякой аппаратурой по ком порту. Самый большой проект который переделывал, какая-то файловая оболочка, 2х панельный менеджер. Встроеный ассемблер использовал. Помню что там строки безпасные, без нуль терминаторов. Енумы, запаписи и указатели строгие, не дают в ногу стрелять. Компилируется быстро, каких-то косяков не помню. Единственно много текста ввдодить, нет фигурных скобок для блоков. Еще С++ тогда считался хакерским, а Паскаль не круто было.


          1. AnotherAnkor
            20.04.2026 20:56

            В перле можно писать в ООП стиле, никаких проблем.

            Паскаль отличается своей многослойностью, а так норм язык.

            Я из тех, кто предпочитает использовать двухпанельники, тестовый редактор и командную строку. Меня таким сложно испугать.


            1. DMGarikk
              20.04.2026 20:56

              Я из тех, кто предпочитает использовать двухпанельники, тестовый редактор и командную строку. Меня таким сложно испугать.

              Чем? процедурным кодом на полмиллиона строк потому что вы двухпанельным менеджером и текстовым редактором пользуетесь?

              Разговор был в начале о том что перл простой, его любой выучит

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

              Java не просто так в энтерпрайзе поселилась, потому что проекты на ней тяжелее сломать и проще поддерживать при условии что половины документации нет, а часть разработчиков уже от старости померло

              а в случае с Перлом это почти про все проекты можно сказать уже, но язык при этом не помогает


              1. avramov
                20.04.2026 20:56

                ну если быть до конца честным, то надо прямо сказать что очень мало программистов может через год разобрать то что написал на любом ЯП. особенно если писал без ТЗ и документации. Что хорошо в perl а так же в java, это автодокументация, кстати в данной статье есть её пример в коде, ну и утилитка perldoc или javadoc в помощь ;)


                1. DMGarikk
                  20.04.2026 20:56

                  ну если быть до конца честным, то надо прямо сказать что очень мало программистов может через год разобрать то что написал на любом ЯП

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

                  Они оба были написаны на питоне, первый очень шакально но очень прямолинейно и хоть с какойто попыткой в архитектуру (хоть извращенную но всётаки), второй в черезчур в Java-стиле

                  мы без проблем всем отделом (4 разраба бэка) за полгода оба раскурили, отрефачили и вывели в прод

                  Забавный был опыт

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

                  ==

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


              1. nuclight
                20.04.2026 20:56

                Позволяет. Поддерживали. А Java не просто так в энтерпрайзе поселилась, а потому что её активно рекламировали и предназначалась она на замену C++ как более простой язык. И то сказать, уже более десяти лет ходит шутка про новый стандарты плюсов:

                это компилируется C++11 Дальше будет только хуже
                это компилируется C++11 Дальше будет только хуже

                …и знаете, Перл гораздо читабельнее вот этого!


            1. unreal_undead2
              20.04.2026 20:56

              Так двухпанельники или командную строку? Истинные адепты командной строки презирают nc-clones.


              1. AnotherAnkor
                20.04.2026 20:56

                Я не настолько старый ) и речь про языки.


              1. checkpoint
                20.04.2026 20:56

                emacs - выбор мастеров! ;)

                Все старички которых знаю, да и я сам, все пользуются либо far2l, либо mc. При этом многие в командной строке настоящие виртуозы. А еще я screen люблю, вместо этих ваших tmux. :)


                1. unreal_undead2
                  20.04.2026 20:56

                  emacs - выбор мастеров! ;)

                  Угу, но dired полноценно не освоил, хотя там по сути весь функционал nc-клонов.


              1. LorHobbit
                20.04.2026 20:56

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

                А вот качественный двухпанельник не заменяет командную строку, а является её очень мощным усилителем и естественным дополнением. В линуксе это mc, в винде - Far. Особенно няшным mc стал, когда в нём наконец-то объединили командную строку под панелями с той, что отображалась по Ctrl+O.


                1. unreal_undead2
                  20.04.2026 20:56

                  для какой-то операции с файлами чуть сложнее cp или mv они используют "стандартный файловый менеджер"

                  Это молодёжь какая то. Я скорее про тех, кто юниксовым шеллом пользуется со времён СМ-4.

                  качественный двухпанельник не заменяет командную строку, а является её очень мощным усилителем и естественным дополнением

                  У меня оно так - но часто понимаю, что вместо шатания по панелькам лучше изначально логичнее раскидать файлы по каталогам и по максимуму скриптовать однообразные операции однострочниками. Но не получается. Сейчас вот с 9front играюсь - панелек там нет и не надо, просто полазить по каталогам и что-то позапускать можно в acme.


                  1. Astrowalk
                    20.04.2026 20:56

                    Исповедую близкий подход (сижу в Linux с нулевого года )): никаких файловых менеджеров. Поддерживаю систему скриптов (кстати, один из них на Perl) и алиасов, работающих интуитивно (для меня), другим чудовищно). Получается довольно эффективно искать в развесистой файловой системе и на результатах поиска (кешируемого в индексном файле) выполнять без мыши операции вроде открытия файла в редакторах на нужной строке, скролла файла, копирования найденной строки или файлового пути в клипборд, мгновенного перехода в нужный каталог и т.д.


                    1. unreal_undead2
                      20.04.2026 20:56

                      У меня дома где то с 1997ого, но всё таки досовские привычки победить не удалось )

                      выполнять без мыши 

                      Есть ещё альтернативная религия - Plan 9 - где, наоборот, вместе с командной строкой очень широко используется мышь, все три кнопки нужны )


                    1. funca
                      20.04.2026 20:56

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


                      1. Astrowalk
                        20.04.2026 20:56

                        Это да. К тому же, когда приходится работать на чужом компьютере (через ssh, например), все нестандартные методы идут лесом.


                      1. KonstantinTokar
                        20.04.2026 20:56

                        И на удивление часто из редакторов только vi.


                      1. unreal_undead2
                        20.04.2026 20:56

                        Это база для сисадмина.

                        Хотя моя начальница на прошлой работе (она из тех, кто перфокарты использовал не только как бумажки для заметок) vi для программирования использовала сама и активно его среди молодых сотрудников пропагандировала - и народ реально пользовался. Меня из Emacs'а уже поздно было вытаскивать )


            1. KonstantinTokar
              20.04.2026 20:56

              Проблема перла в том, что там больше одного ООП стиля. И больше десяти. И каждый стиль рпзвивается и имеет несовместимые версии.


          1. YuriPanchul
            20.04.2026 20:56

            Проблема с перлом, что в нем есть неинтуитивные странности, вплоть до такого шухера что глобальные переменные $a и $b зарезервированы для сортировки. Ну и аргументы $1 $2 $3 нужно все время переназывать


            1. nuclight
              20.04.2026 20:56

              В любом практическом языке есть куча неинтуитвных странностей. Например, в Python - изучал его летом, с некоторой дичи просто остолбеневал. А зачем переназывать $1 $2 $3, если им сразу в регулярке можно дать человеческие имена?


              1. YuriPanchul
                20.04.2026 20:56

                Что вы имеете в виду? С моей точки зрения перловская передача параметров выглядит криво:
                sub f {
                my ($a, $b, $c) = @_;


                1. nuclight
                  20.04.2026 20:56

                  1. Так это не $1 $2, а $_[1] $_[2] - совсем разные вещи! Ибо $1 $2 только в матчинге регэкспов, по большому счету (мы ж не в шелле). Ну и да, $_[1] будет только в каких-нибудь магических обертках, в обычных функциях назовут именами.

                  2. Для тупых не умеющих абстрагироваться от привычек (см. ниже, и вообще привычки это плохо) из других языков - с 5.36 по умолчанию, а до того под “use feature ‘signatures’” доступен синтаксис вида

                             sub foo ($left, $right = 0) {
                                 return $left + $right;
                             }
                  
                  1. Неа, это не криво, это УДОБНО. Это полный контроль над передаваемыми аргументами (чем-то напоминает Erlang), то есть можно вместо идиотизмов типа “перегрузка функций” обработать всё в одном месте: например, позволить субе быть как статической функцией, так и методом, принимать после обязательных параметров опциональный хэш в виде перечня key-value pairs, после которого опять же снова может быть что-то опциональное (которое мы просто проверим по типу концевых элементов, если они есть). То есть принимаем список и возвращаем список, наивысшая абстракция в стиле Lisp. Поэтому опытные перловики предпочитают приучиться к этому “старому” стилю, а не использовать сигнатуры “потому что стало можно”.


                  1. KonstantinTokar
                    20.04.2026 20:56

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


          1. nuclight
            20.04.2026 20:56

            А в чем проблема? Всего лишь полмиллиона и не дельфёв, убежавших вперёд со времен моей юности, а на замороженном Паскале. Я вот работал на импортозамещении биллинга опсоса, 10 миллионов строк, из них миллион на COBOL, вот это было куда веселее!


          1. m0tral
            20.04.2026 20:56

            Это не так, синтаксис basic, pascal очень простой и понятный, как и JavaScript классический, именно поэтому на этих языках раньше и начинали обучение программированию.

            С++, rust тупо не понять, если не знаешь синтаксиса


            1. DMGarikk
              20.04.2026 20:56

              Давайте по другому пример приведу

              Язык 1С, там всё очень просто, даже блин по русски, синтаксис, операторы, там ПРЕДЕЛЬНО простые.

              А потом откроем код большого проекта на нем написанного и попробуем разобраться.

              ==

              еще раз, простота языка != простота разработки крупных проектов на нем


  1. Emergy
    20.04.2026 20:56

    Язык не плохой. Но только без модных фреймворков)


    1. nuclight
      20.04.2026 20:56

      А что такое “модные” ? Свежие? Их есть (Beekeper хоть). Популярные среди разработчиков на данном языке? Их тоже есть, Mojolicious тот же (который потом портировали на JavaScript кстати).

      И да, Perl не исчерпывается вебом, вон AnyEvent достаточно популярен, хотя возрастом уже порядка двух десятилетий.


  1. Anthony_S_Chet
    20.04.2026 20:56

    код на нём выглядит как что‑то между Python, C, и чем‑то своим

    А ничего, что Перл появился когда Питона ещё в планах не было?


    1. unreal_undead2
      20.04.2026 20:56

      Да, я бы скорее awk среди подобных упомянул.


      1. allez24
        20.04.2026 20:56

        Собственно, Ларри Уолл создал Perl именно по причине того, что ему стало не хватать возможностей grep/sed/awk при работе с текстовой информацией.


      1. trinxery
        20.04.2026 20:56

        del


    1. trinxery
      20.04.2026 20:56

      Ну так написано же не "стиль создавался на основе Python", а просто сравнили. Почему бы и нет?


      1. unreal_undead2
        20.04.2026 20:56

        Ну так и не похоже ни разу. Во первых Python вполне читабельный, во вторых там идеологически "There should be one-- and preferably only one --obvious way to do it", что чётко противоречит первому примеру с perl.


  1. nicoms
    20.04.2026 20:56

    Начинал свою карьеру на нём, делали сайты. Язык просто one love


  1. IDDQDesnik
    20.04.2026 20:56

    cat "test... test... test..." | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see'


    1. unreal_undead2
      20.04.2026 20:56

      cat /dev/random | perl # Мне повезёт


    1. HardlinePeak936
      20.04.2026 20:56

      Господи, что это? :)


      1. dtmse
        20.04.2026 20:56

        Вкратце: выполнение rm -rf /
        https://www.dlitz.net/stuff/malicious-perl-sig/


      1. LorHobbit
        20.04.2026 20:56

        Патч Бармина :)


  1. tenzink
    20.04.2026 20:56

    Парсить плюсовый код... А вы смелый


  1. tenzink
    20.04.2026 20:56

    В чём перлу нет равных, так это Code golf (контесты на самый короткий код). Смотришь на результат победителя и замираешь в немом изумлении


    1. dtmse
      20.04.2026 20:56

      Не только на самый короткий, но так же и самый запутанный, или просто визуально красивый. Классический пример - код, печатающий стихотворение "99 bottles of beer on the wall". Ключ -Mre=eval нужен для разрешения исполнения кода, внедренного в регулярные выражения, что в современных версиях perl по умолчанию отключено из соображений безопасности. Раньше он не требовался.

      $ perl -Mre=eval
          ''=~(        '(?{'        .('`'        |'%')        .('['        ^'-')
          .('`'        |'!')        .('`'        |',')        .'"'.        '\\$'
          .'=='        .('['        ^'+')        .('`'        |'/')        .('['
          ^'+')        .'||'        .(';'        &'=')        .(';'        &'=')
          .';-'        .'-'.        '\\$'        .'=;'        .('['        ^'(')
          .('['        ^'.')        .('`'        |'"')        .('!'        ^'+')
         .'_\\{'      .'(\\$'      .';=('.      '\\$=|'      ."\|".(      '`'^'.'
        ).(('`')|    '/').').'    .'\\"'.+(    '{'^'[').    ('`'|'"')    .('`'|'/'
       ).('['^'/')  .('['^'/').  ('`'|',').(  '`'|('%')).  '\\".\\"'.(  '['^('(')).
       '\\"'.('['^  '#').'!!--'  .'\\$=.\\"'  .('{'^'[').  ('`'|'/').(  '`'|"\&").(
       '{'^"\[").(  '`'|"\"").(  '`'|"\%").(  '`'|"\%").(  '['^(')')).  '\\").\\"'.
       ('{'^'[').(  '`'|"\/").(  '`'|"\.").(  '{'^"\[").(  '['^"\/").(  '`'|"\(").(
       '`'|"\%").(  '{'^"\[").(  '['^"\,").(  '`'|"\!").(  '`'|"\,").(  '`'|(',')).
       '\\"\\}'.+(  '['^"\+").(  '['^"\)").(  '`'|"\)").(  '`'|"\.").(  '['^('/')).
       '+_,\\",'.(  '{'^('[')).  ('\\$;!').(  '!'^"\+").(  '{'^"\/").(  '`'|"\!").(
       '`'|"\+").(  '`'|"\%").(  '{'^"\[").(  '`'|"\/").(  '`'|"\.").(  '`'|"\%").(
       '{'^"\[").(  '`'|"\$").(  '`'|"\/").(  '['^"\,").(  '`'|('.')).  ','.(('{')^
       '[').("\["^  '+').("\`"|  '!').("\["^  '(').("\["^  '(').("\{"^  '[').("\`"|
       ')').("\["^  '/').("\{"^  '[').("\`"|  '!').("\["^  ')').("\`"|  '/').("\["^
       '.').("\`"|  '.').("\`"|  '$')."\,".(  '!'^('+')).  '\\",_,\\"'  .'!'.("\!"^
       '+').("\!"^  '+').'\\"'.  ('['^',').(  '`'|"\(").(  '`'|"\)").(  '`'|"\,").(
       '`'|('%')).  '++\\$="})'  );$:=('.')^  '~';$~='@'|  '(';$^=')'^  '[';$/='`';
      

      Почитать о том, как был создан этот шедевр, можно здесь

      А создатель языка Larry Wall был неоднократным победителем конкурсов IOCCC, пример его кода - https://github.com/ioccc-src/winner/blob/master/1986/wall/wall.c


      1. tenzink
        20.04.2026 20:56

        Обалдеть - это нереально круто


  1. PjaniyAdmin
    20.04.2026 20:56

    Помнится я выходной себе заработал, у нас был спор с начальником, что будет быстрее парсить файлы его поделка на sed или моя на Перл. Моя поделка оказалась быстрее :)


    1. Daiichi
      20.04.2026 20:56

      Помнится я выходной себе заработал, у нас был спор с начальником, что будет быстрее парсить файлы его поделка на sed или моя на Перл. Моя поделка оказалась быстрее :)

      Мне выходной никто не дал, но я тоже удивил своего начальника, продемонстрировав ему, как скрипт на перле пережёвывает текстовые логи сквида за вчерашний день минут за десять, в то время как он заказывал утром отчёт по логам своей микрософт прокси из базы данных MS SQL и ждал до обеда, пока оснастка родит ему этот отчёт.

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

      Правда, написанный им генератор работал где-то полчаса, сказывалась разница в количестве клиентов сквида и микрософтовской прокси. Но, всё равно, экономия времени по сравнению с родной оснасткой микрософт прокси оказалась просто колоссальной.


  1. NoSkill24
    20.04.2026 20:56

    Если скачать исходники Perl и скомпилировать, то в при компиляции будет создана miniperl - облегченная версия интерпретатора Perl. Сама она используется для дальнейшей сборки Perl. Это всего один исполняемый файл, который весит всего пару мегабайт!

    Если компилировать в Windows с помощью древнего Windows Server 2003 R2 SDK, то получите файл miniperl.exe, который будет слинкован с древней версией msvcrt.dll и будет работать в любой версии Windows, начиная с XP без всяких дополнительных runtime библиотек.

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

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


    1. checkpoint
      20.04.2026 20:56

      "Век живи, век учисть", сказал поручик. Возьмем на вооружение.


      1. unreal_undead2
        20.04.2026 20:56

        Ещё как вариант - busybox, который есть и под винду. Там grep/sed/awk, для мелких задач хватит. Perl хорош, когда пользуешься постоянно - иначе забываются специфические вещи типа контекстов и писать тяжело. А по awk и вспоминать особо нечего, если что по мануалу за несколько минут можно весь язык в памяти обновить )


  1. checkpoint
    20.04.2026 20:56

    sudo cpanm MODULE

    У меня в системе (FreeBSD) нет никакого cpanm. Использую классический вариант установки модулей:

    sudo perl -MCPAN -e 'install SomeModuleName'

    Надо заметить, что в отличии от многих популярных ныне языков программирования, CPAN - это архив с исходными кодами, а не репозиторий готовых пакетов. При выполнении команды install будет вызвана система сборки, которая создаст Makefile и запустит компиляцию C/C++ кода (если он присутствует в модуле), а результирующая библиотека (.so файл) будет установлена в дерево каталогов данной версии интерпретатора Perl. Но бывают и модули написанные чисто на Perl, они устанавливаются без компиляции.

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

    На данный момент архив CPAN содержит более 220 000 модулей на все случаи жизни.


    1. esher
      20.04.2026 20:56

      Абсолютно легко добавить cpanm во фрю, ведь это апп-модуль App::cpanminus ;-)


      1. checkpoint
        20.04.2026 20:56

        Абсолютно легко добавить cpanm во фрю

        Можно, но зачем ? ;)


    1. nuclight
      20.04.2026 20:56

      Зачем -MCPAN, если можно cpan -I -i ? И установить local::lib конечно.


      1. checkpoint
        20.04.2026 20:56

        Этот скрипт cpan помимо local::lib имеет еще зависимости:

        use App::Cpan;
        use CPAN::Version;

        Зачем, если можно без них и встроенными средствами ?


        1. nuclight
          20.04.2026 20:56

          Зачем страдать “встроенными”, если можно проще? Вся мощь что перла, что фряхи - в легкой инсталляции нужных сторонних пакетов.


          1. checkpoint
            20.04.2026 20:56

            Зависимости следует искоренять! (с) мой.


            1. nuclight
              20.04.2026 20:56

              Хаха, и что вместо? Статически линковать всё в один огромный бинарь, как делают в Go или Rust? Спасибо, но нет, юниксы от этой глупости ушли еще более четверти века назад.


              1. checkpoint
                20.04.2026 20:56

                Хаха, и что вместо? Статически линковать всё в один огромный бинарь,

                В нынешних условиях это вполне себе отличное решение. И бинарь нифига не огромный получается.


                1. nuclight
                  20.04.2026 20:56

                  Не огромный? Точно? Я вспоминаю Telegram Desktop на пару гигабайт в отладочной версии… щас уже наверняка куда больше.

                  Нет, не отличное это решение, а говно от кукловодов для идиотов.


                  1. checkpoint
                    20.04.2026 20:56

                    А без дебага сколько ? Прошу цифры в студию.


    1. KonstantinTokar
      20.04.2026 20:56

      Сейчас есть замена - cpm - сильно быстрее работает


  1. tik4
    20.04.2026 20:56

    Познакомился с Perl, когда пришлось погрузиться в тему написания скриптов для ПО Ansys CFX. А поскольку Ansys обильно скупал различные другие софты, каждый из которых поддерживал скрипты только на каком-то конкретном языке, то под капотом там собиралась знатная солянка. Поэтому в рамках одной задачи газодинамика/тепло/прочность собиралась пачка взаимосвязанных скриптов на разных языках, например Python + Perl + внутренние языки Apdl и ccl. Было весело :) Но ни до, ни после больше с Perl не встречался, видимо какая-то узкая ниша за ним осталась и все.


    1. LorHobbit
      20.04.2026 20:56

      Строкодробилка - вот его родная ниша, как тогда, так и сейчас. И в этом ему нет равных. Пережевать текст (например, логи, про что выше писали, но не только), выделить нужное, упорядочить - вот стихия Перла.


  1. Q2W
    20.04.2026 20:56

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


    1. haqreu
      20.04.2026 20:56

      Да какая там оптимизация с динамическим связыванием переменных. Внимание, вопрос:
      Что выведет на экран следующая программа? :)

      #!/usr/bin/perl
      
      sub foo {
          print "$x, $y\n"
      }
      
      sub bar {
          local $x = 0;
          foo()
      }
      
      sub baz {
          local $y = 0;
          bar()
      }
      
      $x = 1337;
      $y = 42;
      foo();
      bar();
      baz()


      1. nuclight
        20.04.2026 20:56

        Для кого-то новости фрагменты из документации, которые спрашивают на собеседованиях на перловика? Хотя тащемта любой человек, использовавший local в шелл-скриптах, поймет данный конкретный пример и без неё - а в них больше ничего и нету, в Перле же тридцать лет my есть, с котором поведение станет “ожидаемым” (это ведь был пример из разряда “смотрите как в этом языке неожиданно и неинтуитивно”, да?).


        1. haqreu
          20.04.2026 20:56

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


          1. nuclight
            20.04.2026 20:56

            А причем тут тогда Перл? Такое будет и в любом другом динамическом языке, хоть бидоне, хоть жабаскрипте.


            1. haqreu
              20.04.2026 20:56

              Нет. И питон, и джаваскрипт имеют статическое (лексическое) связывание переменных: когда в какой-то функции вы пишете x, то интерпретатор ищет такую переменную в тексте программы. Перл же ищет x в стеке вызовов. У вас не получится переписать вышеприведённый пример на питоне.


              1. sappience
                20.04.2026 20:56

                Так и Perl имеет lexical scope variables. И они являются предпочтительными. local используется редко, обычно все переменные определяются как my и тогда они связаны лексически и работают быстро.


    1. domix32
      20.04.2026 20:56

      Как-то так он теперь не Perl, а Raku.


      1. nuclight
        20.04.2026 20:56

        Это то, что было под названием Perl 6. А пятый так и остался теперь снова единственный perl.


    1. nuclight
      20.04.2026 20:56

      Для своих задач (те же тексты) он уже хорошо оптимизирован, видел сравнение кода на Go “в лоб”, которое оказалось в примерно 40 раз медленнее перлового решения той же задачи.