あなたはそうです、特に、属性がそれほど複雑ではないので、この分野での文書はあまり明確ではありません。あなたは、サブルーチンの属性を定義する場合は、次のように:
sub some_method :Foo { }
Perlがあなたのプログラムをコンパイル中には、(これは重要です)、現在のパッケージまたはその親クラスのいずれかで魔法のサブMODIFY_CODE_ATTRIBUTES
を探します。これは、現在のパッケージの名前、サブルーチンへの参照、およびこのサブルーチン用に定義された属性のリストとともに呼び出されます。このハンドラが存在しない場合、コンパイルは失敗します。
このハンドラで行うことは、あなた次第です。はい、そうです。まったく隠された魔法はありません。エラーを通知する場合は、問題のある属性の名前を返すと、コンパイルに失敗し、「無効な属性」メッセージが表示されます。もし何かかわらず、(そこに誰かがこのハンドラは、パッケージ名とサブルーチンのリファレンスを渡さ
use attributes;
my @attrs = attributes::get(\&some_method);
言うたびに呼び出されますFETCH_CODE_ATTRIBUTES
と呼ばれる別のハンドラがあり、かつサブルーチンの属性のリストを返すことになっている
本当にやるのはあなた次第です)。ここで
は、後で照会することができ、任意の属性を持つメソッドの簡単な「タグ付け」を有効にする例です。
今
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
要約すると、属性は逆に彼らは非常に柔軟になりそのあまり行わない:あなたは「属性」本物としてそれらを使用することができます(この例で示すように)、何かを実装しますのようなデコレータ(Sinan's answer)、またはあなたの邪悪な目的のために。
優れた答え! :D – gideon