You are right, the documentation is not very clear in this area, especially since the attributes are not so complicated. If you define a subroutine attribute, for example:
sub some_method :Foo { }
Perl will be when 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 link to your subroutine, and a list of attributes defined for that subroutine. If this handler does not exist, compilation will fail.
What you do in this handler is completely up to you. Yes, it's right. No hidden magic at all. If you want to report an error, then when the name of the violating attributes is returned, compilation will end with the message "invalid attribute".
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 receives the passed package name and subroutine and should return a list of attributes of the subroutine (although what you really do is up to you again).
Here is an example to enable a simple “labeling” of methods with arbitrary attributes, which you may request later:
package MyClass; use Scalar::Util qw( refaddr ); my %attrs;
Now in MyClass and in all its subclasses you can use arbitrary attributes and query them using attributes::get() :
package SomeClass; use base 'MyClass'; use attributes;
In general, attributes do not 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 Sinan's answer ) or for your own insidious purposes.
trendels Jun 12 '09 at 15:27 2009-06-12 15:27
source share