Атрибуты позволяют вам аннотировать переменные для выполнения автоматической магии за кулисами. Аналогичная концепция - Java-аннотации . Вот небольшой пример, который может помочь. Он использует Attribute::Handlers
для создания атрибутов loud
.
use Attribute::Handlers;
sub UNIVERSAL::loud : ATTR(CODE) {
my ( $pkg, $sym, $code ) = @_;
no warnings 'redefine';
*{$sym} = sub {
return uc $code->(@_);
};
}
sub foo : loud {
return "this is $_[0]";
}
say foo("a spoon");
say foo("a fork");
Всякий раз, когда подпрограмма объявляется с атрибутом loud
, обратный вызов UNIVERSAL::loud
вызывает раскрытие метаинформации в подпрограмме. Я переопределил функцию для фактического вызова анонимной подпрограммы, которая, в свою очередь, вызывает исходную подпрограмму и передает ее uc
Это выводит:
THIS IS A SPOON
THIS IS A FORK
Теперь давайте рассмотрим пример переменной из SYNOPSIS :
my ($x,@y,%z) : Bent = 1;
Разбивая это на небольшой оператор perl, не принимая во внимание атрибуты, которые мы имеем
my $x : Bent
$x = 1;
my @y : Bent
@y = 1;
my %Z : Bent
%z = 1;
Теперь мы можем видеть, что каждой переменной кратко приписывается аннотация Bent, а также присваивается всем переменным значение 1. Вот, пожалуй, более интересный пример:
use Attribute::Handlers;
use Tie::Toggle;
sub UNIVERSAL::Toggle : ATTR(SCALAR) {
my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
my @data = ref $data eq 'ARRAY' ? @$data : $data;
tie $$referent, 'Tie::Toggle', @data;
}
my $x : Toggle;
say "x is ", $x;
say "x is ", $x;
say "x is ", $x;
Какие выходы:
x is
x is 1
x is
Вы можете использовать это для ведения журналов, создания тестовых аннотаций, добавления деталей типа к переменным, синтаксического сахара, создания ролевых композиций в стиле «лось» и многих других интересных вещей.
Также смотрите этот вопрос: Как работают атрибуты метода Perl? .