Perl 方法属性如何工作? [英] How do Perl method attributes work?

查看:19
本文介绍了Perl 方法属性如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

A little known built-in Perl feature is attributes. However, the official documentation is doing a rather bad job introducing newbies to the concept. At the same time, frameworks like Catalyst use attributes extensively which seems to make many things easier there. Since using something without knowing the implications sucks a bit, I'd like to know the details. Syntax-wise they look like Python's decorators, but the documentation implies something simpler.

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

Could you explain (with real-world examples if possible) what attributes are good for and what happens behind the doors?

推荐答案

你说得对,这方面的文档不是很清楚,尤其是属性没有那么复杂.如果你定义一个子程序属性,像这样:

You are right, the documentation is not very clear in this area, especially since attributes are not so complicated. If you define a subroutine attribute, like this:

sub some_method :Foo { }

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

Perl will while compiling your program (this is important) look for the magic sub MODIFY_CODE_ATTRIBUTES in the current package or any of its parent classes. This will be called with the name of the current package, a reference to your subroutine, and a list of the attributes defined for this subroutine. If this handler does not exist, compilation will fail.

你在这个处理程序中做什么完全取决于你.是的,这是正确的.没有任何隐藏的魔法.如果您想发出错误信号,返回有问题的属性的名称将导致编译失败并显示无效属性";消息.

What you do in this handler is entirely up to you. Yes, that's right. No hidden magic whatsoever. If you want to signal an error, returning the name of the offending attributes will cause the compilation to fail with an "invalid attribute" message.

还有一个名为 FETCH_CODE_ATTRIBUTES 的处理程序,只要有人说,就会调用它

There is another handler called FETCH_CODE_ATTRIBUTES that will be called whenever someone says

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

这个处理程序被传递了包名和子程序引用,并且应该返回子程序属性的列表(尽管你真正做的还是取决于你).

This handler gets passed the package name and subroutine reference, and is supposed to return a list of the subroutine's attributes (though what you really do is again up to you).

这是一个启用简单标记"的示例.具有任意属性的方法,您可以稍后查询:

Here is an example to enable simple "tagging" of methods with arbitrary attributes, which you can query later:

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():

Now, in MyClass and all its subclasses, you can use arbitrary attributes, and query them using 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 的文章),或用于您自己的狡猾目的.

In summary, attributes don't do very much which on the other hand makes them very flexible: You can use them as real "attributes" (as shown in this example), implement something like decorators (see Mike Friedman's article), or for your own devious purposes.

这篇关于Perl 方法属性如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆