Named entities in Perl--variables and functions--can have additional metadata attached to them in the form of attributes. Attributes are arbitrary names and values used with certain types of metaprogramming (code_generation).
Attribute declaration syntax is awkward, and using attributes effectively is more art than science. Most programs never use them, but when used well they offer clarity and maintenance benefits.
A simple attribute is a colon-preceded identifier attached to a declaration:
These declarations will cause the invocation of attribute handlers named hidden
and ScienceProject
, if they exist for the appropriate type (scalars and functions, respectively). These handlers can do anything. If the appropriate handlers do not exist, Perl will throw a compile-time exception.
Attributes may include a list of parameters. Perl treats these parameters as lists of constant strings and only strings. The Test::Class
module from the CPAN uses such parametric arguments to good effect:
The Test
attribute identifies methods which include test assertions, and optionally identifies the number of assertions the method intends to run. While introspection (reflection) of these classes could discover the appropriate test methods, given well-designed solid heuristics, the :Test
attribute makes your intent clear.
The setup
and teardown
parameters allow test classes to define their own support methods without worrying about conflicts with other such methods in other classes. This separates the concern of specifying what this class must do with the concern of how other classes do their work, and offers great flexibility.
Attributes have their drawbacks. The canonical pragma for working with attributes (the attributes
pragma) has listed its interface as experimental for many years. Damian Conway's core module Attribute::Handlers
simplifies their implementation. Andrew Main's Attribute::Lexical
is a newer approach. Prefer either to attributes
whenever possible.
The worst feature of attributes is their propensity to produce weird syntactic action at a distance. Given a snippet of code with attributes, can you predict their effect? Well written documentation helps, but if an innocent-looking declaration on a lexical variable stores a reference to that variable somewhere, your expectations of its lifespan may be wrong. Likewise, a handler may wrap a function in another function and replace it in the symbol table without your knowledge--consider a :memoize
attribute which automatically invokes the core Memoize
module.
Attributes are available when you need them to solve difficult problems. They can be very useful, used properly--but most programs never need them.
Hey! The above document had some coding errors, which are explained below:
- Around line 3:
-
A non-empty Z<>