Особенности (Traits) – это удобный и расширяемый способ присоединения метаданных к различным видам объектов в Perl 6. Рассмотрим пример особенности с is cached, автоматически кеширующей возвращаемое функцией значение в зависимости от переданных аргументов.
Особенность применяется с глаголом, в данном случае – is. Он указывается в имени функции, обрабатывающей особенность, здесь — trait_mod:. Аргументами обработчика являются объект, к которому применяется особенность, и название особенности (cached) в качестве именованного аргумента.
В нашем примере вызывается метод .wrap функции, но вы, разумеется, можете вызывать что угодно. Обычно это используется для включения в функцию ролей или добавления их в таблицу распределения.
Особенности можно применять не только с функциями – но и с параметрами, атрибутами и переменными. К примеру, аксессоры с доступом к записи реализуются через особенность rw:
Также особенности используются для присоединения документации к классам и атрибутам, отметке параметров функций как перезаписываемых, и объявлений у классов наследования и применения к ним ролей.
# следующий код вызывается, когда к функции
# добавляется 'is cached'
multi sub trait_mod:<is>(Routine $r, :$cached!) {
my %cache;
# обернём функцию в блок, который
$r.wrap(-> $arg {
# ищет аргумент в кеше
%cache{$arg}:exists
?? %cache{$arg}
# ... и вызывает оригинал, если он не найден
!! (%cache{$arg} = callwith($arg))
}
);
}
# пример применения:
sub fib($x) is cached {
say("fib($x)");
$x <= 1 ?? 1 !! fib($x - 1) + fib($x - 2);
}
# для всех значений от 0 до 10 происходит лишь по одному вызову
say fib(10);
Особенность применяется с глаголом, в данном случае – is. Он указывается в имени функции, обрабатывающей особенность, здесь — trait_mod:. Аргументами обработчика являются объект, к которому применяется особенность, и название особенности (cached) в качестве именованного аргумента.
В нашем примере вызывается метод .wrap функции, но вы, разумеется, можете вызывать что угодно. Обычно это используется для включения в функцию ролей или добавления их в таблицу распределения.
Особенности можно применять не только с функциями – но и с параметрами, атрибутами и переменными. К примеру, аксессоры с доступом к записи реализуются через особенность rw:
class Book {
has @.pages is rw;
...
}
Также особенности используются для присоединения документации к классам и атрибутам, отметке параметров функций как перезаписываемых, и объявлений у классов наследования и применения к ним ролей.
Neuronix
Писал я когда-то на Perl 5, все его ругали за запутанный и непонятный синтаксис… Смотрю, ничего не изменилось.