我根本不了解Perl子例程的属性。

我从未在实际代码中看到它们,并且 perldoc perlsub perldoc attributes 无法回答我的问题:

  • 属性对什么有用?
  • 他们带来了Perl最佳实践中尚不存在的东西?
  • 是否有任何使用属性的CPAN模块(众所周知的或其他)?

  • 如果有人可以按原样使用属性的详细示例放在一起,那就太好了。

    对于像我这样笨拙的人,属性是以下 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/

    10-11 17:47
    查看更多