attributes#

📦 min

The machinery behind sub name :attr and my $x :attr: applying the built-in attributes, handing the others to the package that defines them, and reading attributes back.

Perl loads it by itself when it compiles an attribute; use attributes is needed only to call its functions. The built-in attributes are lvalue, method, const and prototype(...) on a sub, and shared on a variable. Any other attribute goes to the package’s MODIFY_CODE_ATTRIBUTES (or _SCALAR_, _ARRAY_, _HASH_), called as ($package, $ref, @attributes); what it returns is the list it did not accept, and those die “Invalid CODE attribute”. FETCH_CODE_ATTRIBUTES (and the others) add a package’s own attributes to what attributes::get returns.

This is attributes 0.37; attributes.pm is upstream’s, and its XS half is native.

Synopsis#

use attributes;

our $count;
sub counter :lvalue { $count }
counter() = 5;                                   # $count is now 5

sub method_sub :method { 1 }
print join(',', attributes::get(\&counter)), "\n";    # lvalue
print attributes::reftype(\&counter), "\n";           # CODE

package My::Attrs;
my @seen;
sub MODIFY_CODE_ATTRIBUTES { my ($pkg, $ref, @attrs) = @_; push @seen, @attrs; return }
sub handler :Cached :Log { 1 }                   # @seen is (Cached, Log)

Functions#

  • attributes::get($ref) - the attributes of what $ref points to: the built-in ones, then those of the package’s FETCH_*_ATTRIBUTES.

  • attributes::reftype($ref) - the type $ref points to (CODE, HASH, …), ignoring blessing, like Scalar::Util::reftype.

  • use attributes PACKAGE, \&sub, ATTRIBUTES - apply attributes at run time, as sub name :ATTRIBUTES does at compile time.

Differences from upstream#

None: upstream’s tests pass unchanged (t/81-xs-native/attributes/100-upstream-op-attrs.t, 110-upstream-uni-attrs.t), and the rest of t/81-xs-native/attributes checks against perl 5.44.