Это не Perl вашего дедушки. Часть 2

Начало статьи в этом топике.

Обработка даты и времени

Долгое время стандартные функции Perl для работы с датами и временем также были тесно связаны с корнями Unix. Возможно, вы видели такой код:
my @datetime = localtime();

Функция localtime() возвращает список значений, представляющих различные части текущего местного времени. Список значений, которые вы возвращаете:
  • Секунды
  • Минуты
  • Часы
  • День месяца
  • Номер месяца (0-11)
  • Год (на самом деле год – 1900)
  • День недели (0 = воскресенье, 6 = суббота)
  • День года
  • Логический флаг, указывающий, используется ли летнее время.
С этим приходится иметь дело, и это очень странные наборы значений. Если вы хотите создать метку времени, совместимую с ISO8601, вам понадобится что-то вроде этого:
printf '%4d-%02d-%02dT%02d:%02d:%02d,
       $date[5]+1900, $date[4]+1, $date[3],
       $date[2], $date[1], $date[0];

Или, возможно, вы знаете об относительно малоизвестной функции strftime(), которая спрятана в библиотеке POSIX.
use POSIX 'strftime';
print strftime('%Y-%m-%dT%H:%M:%S', localtime());

Функция strftime() принимает определение строки формата, за которым следует список значений, описывающих дату/время, которые удобно имеют те же самые недостатки, что и значения, возвращаемые функцией localtime(). Все это работает вместе, если вы знаете, как работают эти функции. Но, похоже, об этом знают очень немногие.

Начиная с Perl 5.10, стандартная библиотека включает модуль Time::Piece. Когда вы используете Time::Piece в своем коде, он переопределяет localtime() и заменяет его функцией, которая возвращает объект, содержащий сведения о текущем времени и дате. Этот объект имеет метод strftime();
use Time::Piece;

my $time = localtime;
print  $time->strftime('%Y-%m-%dT%H:%M:%S');

И у него также есть несколько других методов для доступа к информации о времени и дате. Это включает:
$time->min
$time->hour
$time->year # Текущий год
$time->mon # 1 - 12
$time->month # Январь - Декабрь
$time->wday # Понедельник = 1, Суббота = 6
$time->day # Понедельник - Суббота

Есть и более непонятная информация:
$time->is_leap_year
$time->txoffset
$time->julian_day

Использование Time::Piece почти наверняка упростит написание кода для обработки даты и времени и (что более важно) упростит его чтение и понимание.

Сигнатуры функций

Еще одна область, в которой Perl ставит в тупик людей, привыкших к более традиционным языкам, — это обработка параметров подпрограмм. В Perl все параметры передаются подпрограмме в массиве с именем @_, и программист должен извлечь данные из этого массива. Таким образом, почти каждая подпрограмма Perl начинается с кода, который выглядит следующим образом:
sub my_subroutine {
    my ($foo, $bar, $baz) = @_;
      …
    }

Это берет первые три значения из @_ и сохраняет их в переменных с именами $foo, $bar и $baz. Затем вы можете использовать эти переменные, чтобы делать все, что вам нужно от вашей подпрограммы. Конечно, вам не обязательно использовать эти переменные; вы можете использовать значения из массива напрямую. Но так как это оставит вас с переменными с именами $_[0], $_[1] и $_[2], это, вероятно, не приведет к особо читаемому коду. Вы можете понять, почему большинству людей нравится копировать значения из массива в переменные в начале подпрограммы.

Конечно, в большинстве языков это не так. В большинстве языков у вас будет список имен переменных после имени подпрограммы, и параметры будут переданы непосредственно в них. Что ж, начиная с версии 5.36 (которая была выпущена ранее этим летом) в Perl это тоже есть.

Вы включаете эту функцию с помощью функции use feature 'signatures', и это выглядит так:
use feature ('say', 'signatures');

    sub my_subroutine ($foo, $bar, $baz) {
      say "$foo - $bar - $baz";
    }

    my_subroutine('sound', 'and', 'vision');

Три параметра, которые вы передаете подпрограмме, копируются непосредственно в переменные при вызове подпрограммы. Вам больше не нужно делать это самостоятельно.

Сигнатуры подпрограмм имеют много других особенностей. Вы можете, например, объявить значения по умолчанию для параметров.
use feature ('say', 'signatures');

    sub my_subroutine ($foo, $bar, $baz = 'fury') {
      say "$foo - $bar - $baz";
    }

     my_subroutine('sound', 'and');

В этом случае, если вы не передадите подпрограмме третий параметр, $baz будет присвоено значение по умолчанию «fury».

Вы также можете передать массив (или список значений, которые будут храниться в массиве):
sub my_subroutine ($foo, $bar, @baz) {
      say "$foo - $bar - ", join(':', @baz);
    }

    my_subroutine('some', 'numbers', 1 .. 10);

И что-то очень похожее работает и для хэшей:
sub my_subroutine (%params) {
      for my $pname (keys %params) {
        say "$pname -> $params{$pname}";
      }
    }

    my_subroutine( run => 1, dir => '/home/me');

Есть много других функций. Подробности смотрите на странице руководства perlsub.

Дополнительная информация

В этой статье я лишь немного коснулся тех изменений, которые произошли с Perl за последние пятнадцать лет. Есть много других улучшений, о которых нужно узнать.

Каждая новая версия Perl поставляется с справочной страницей «perldelta», в которой объясняются отличия от предыдущей версии. Таким образом, perldelta, поставляемая с версией 5.36, описывает все, что изменилось с версии 5.34 (Perl использует нечетные номера версий для обозначения разрабатываемых версий, поэтому только четные номера считаются производственными выпусками). Каждая версия также будет включать perldeltas из всех предыдущих версий (ну, вернемся к версии 5.4, которая была первой версией, включившей эту документацию). Последняя версия всегда называется просто «perldelta», а более старые переименовываются, чтобы включить номер версии. Поэтому документ, описывающий различия между 5.32 и 5.34, называется «perl5340delta».

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

Что дальше?

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

Вероятно, самым интересным проектом, над которым сейчас работает команда разработчиков Perl, является Corinna. Это совершенно новая среда объектно-ориентированного программирования, которая записывается в ядро ​​Perl. Нынешняя объектно-ориентированная среда Perl очень мощная и гибкая, но она несколько примитивна. Corinna стремится привнести в Perl лучшее из современной теории объектного программирования. Разработка шла пару месяцев. В настоящее время планируется включить базовую версию в Perl 5.38, который выйдет во втором квартале следующего года. Это будет дополнением к существующей объектно-ориентированной среде Perl — от нее зависит слишком много кода, чтобы кто-то мог подумать об ее удалении.

Помимо этого, команда разработчиков Perl присматривается к увеличению количества основных версий. Существование Perl 6 (даже если он сейчас называется Raku) означает, что мы не будем использовать этот номер версии, чтобы не сбивать людей с толку. Следующей основной версией Perl будет Perl 7. Несколько месяцев назад Руководящий совет Perl опубликовал сообщение в блоге, в котором рассказывается о их планах на будущее Perl, включая Perl 7. По сути, они говорят, что будут продолжать добавлять новые версии. функций в Perl, и в какой-то момент они вполне могут решить, что было добавлено достаточно функций, чтобы было целесообразно поднять основную версию. Они не говорят об этом прямо, но я подозреваю, что Corinna вполне может рассматриваться как достаточно большое изменение языка, чтобы сделать вероятным изменение номера версии.

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

Переводил с английского ваш покорный слуга.
Поделиться:

Похожие публикации

Тут ничего нет

Нет комментариев