Example 2
package Dispatch::Declare::Attr; use strict; use warnings; use Attribute::Handlers; my %stash = (); sub import { no strict 'refs'; *{ caller() . '::run' } = \&run; } sub UNIVERSAL::Dispatch : ATTR(CODE) { my ( $package, $symbol, $referent, $attr, $data, $phase ) = @_; my $name = $data || *$symbol{NAME}; $stash{ uc $name } = $referent; } sub run { my $key = shift; if ( exists $stash->{ uc $key } ) { return $stash->{ uc $key }->(@_); } elsif ( exists $stash->{'DEFAULT'} ) { return $stash->{'DEFAULT'}->(@_); } } package main; use Dispatch::Declare::Attr; print run 'plan9'; sub plan_nine : Dispatch('plan9') { return 'Clata verata nicto' . "\n"; }
- OUTPUT:
Clata verata nicto
--
Arguments passed to your attribute
- $package
- The name of the package the item the attribute is being applied to is located in.
- $symbol
- The typeglob that contains the item, if there is one. For example, the typeglob can be used to replace a subroutine that an attribute is applied to with a wrapping subroutine (this is in fact how Attribute::Attempts functions. This value might be a constant "LEXICAL" or "ANON" instead of a typeglob if the item isn't being entered in the stash.
- $referent
- A reference to the variable that the attribute is being applied.
- $attr
The name of the attribute that's being applied.
- $data
- The arguments that were passed in the data. For example, in the code above we passed 'tries => 3, delay => 2' to the attempts subroutine and that would be found in this variable. Attribute::Handlers will attempt to turn these values into a Perl data structure, but failing this this will be just passed in as a string.
- $phase
- Where exactly the attribute is being executed in the lifetime of the program (at BEGIN time, CHECK time, etc)
---
Where are attributes useful
- Debugging
- Abstracting complex behavior with a simple syntax
- Automating --help for script with command line options
- Many things I can't think of