gpt4 book ai didi

perl - Perl 方法属性如何工作?

转载 作者:行者123 更新时间:2023-12-02 00:36:09 25 4
gpt4 key购买 nike

一个鲜为人知的内置 Perl 功能是属性。不过官方documentation在向新手介绍这个概念方面做得相当糟糕。与此同时,像 Catalyst 这样的框架广泛使用属性,这似乎使许多事情变得更容易。因为在不知道其含义的情况下使用某些东西有点糟糕,所以我想知道细节。从语法上看,它们看起来像 Python 的装饰器,但文档暗示了一些更简单的东西。

您能解释一下(如果可能的话,用现实世界的例子)哪些属性有好处以及背后会发生什么?

最佳答案

你是对的,文档在这方面不是很清楚,特别是因为属性并不那么复杂。如果您定义子例程属性,如下所示:

sub some_method :Foo { }

Perl 将在编译程序时(这很重要)在当前包或其任何父类中查找魔术子MODIFY_CODE_ATTRIBUTES。这将使用当前包的名称、对子例程的引用以及为此子例程定义的属性列表来调用。如果该处理程序不存在,编译将失败。

您在此处理程序中执行的操作完全取决于您。恩,那就对了。没有任何隐藏的魔法。如果您想发出错误信号,则返回有问题的属性的名称将导致编译失败,并显示“无效属性”消息。

还有另一个名为 FETCH_CODE_ATTRIBUTES 的处理程序,每当有人说时就会调用它

use attributes;
my @attrs = attributes::get(\&some_method);

此处理程序传递包名称和子例程引用,并且应该返回子例程的属性列表(尽管您真正要做的又取决于您)。

下面是一个示例,用于启用具有任意属性的方法的简单“标记”,您可以稍后查询:

package MyClass;
use Scalar::Util qw( refaddr );

my %attrs; # package variable to store attribute lists by coderef address

sub MODIFY_CODE_ATTRIBUTES {
my ($package, $subref, @attrs) = @_;
$attrs{ refaddr $subref } = \@attrs;
return;
}

sub FETCH_CODE_ATTRIBUTES {
my ($package, $subref) = @_;
my $attrs = $attrs{ refaddr $subref };
return @$attrs;
}

1;

现在,在 MyClass 及其所有子类中,您可以使用任意属性,并使用 attributes::get() 查询它们:

package SomeClass;
use base 'MyClass';
use attributes;

# set attributes
sub hello :Foo :Bar { }

# query attributes
print "hello() in SomeClass has attributes: ",
join ', ', attributes::get(SomeClass->can('hello'));

1;
__END__
hello() in SomeClass has attributes: Foo, Bar

总而言之,属性的作用并不大,但另一方面却使它们非常灵活:您可以将它们用作真正的“属性”(如本示例所示),实现类似装饰器的东西(请参阅 Mike Friedman's article ) ,或用于您自己的不正当目的。

关于perl - Perl 方法属性如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/987059/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com