我根本不了解Perl子例程的属性。
我从未在实际代码中看到它们,并且 perldoc perlsub
和 perldoc attributes
无法回答我的问题:
如果有人可以按原样使用属性的详细示例放在一起,那就太好了。
对于像我这样笨拙的人,属性是以下
attributes SYNOPSIS
示例中冒号后面的参数:sub foo : method ;
my ($x,@y,%z) : Bent = 1;
my $s = sub : method { ... };
use attributes (); # optional, to get subroutine declarations
my @attrlist = attributes::get(\&foo);
use attributes 'get'; # import the attributes::get subroutine
my @attrlist = get \&foo;
最佳答案
属性允许您注释变量以在后台执行自动魔术。类似的概念是java annotations。这是一个可能有用的小例子。它使用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
您可以使用它进行日志记录,创建测试注释,将类型详细信息添加到变量,语法糖,执行驼鹿式角色组合以及许多其他有趣的事情。
另请参阅此问题:How do Perl method attributes work?。
关于perl - 什么时候应该使用子例程属性?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8455997/