# man > Attribute::Handlers

<think>The user wants me to transform this Perl man page for Attribute::Handlers into Open Knowledge Format (OKF) Markdown. Let me analyze the content and restructure it according to the rules:

1. YAML frontmatter with required fields
2. Clean Markdown only, no HTML
3. Preserve all technical information
4. No emoji
5. Code blocks with language tags
6. Function names in backticks
7. Cross-references as Markdown links

Let me organize this:

Section structure:
- YAML frontmatter
- Quick Reference
- Name
- Synopsis
- Options/Features
- Examples
- See Also
- Exit Codes (skip - not applicable)

The content is about Attribute::Handlers module. Let me condense it while preserving all technical info.

Key features/topics to cover:
1. Basic attribute handlers
2. Handler argument list
3. Typed lexicals
4. Type-specific handlers (SCALAR, ARRAY, HASH, CODE, ANY)
5. Non-interpretive handlers (RAWDATA)
6. Phase-specific handlers (BEGIN, CHECK, INIT, END)
7. autotie interface
8. autotieref
9. findsym utility
10. Diagnostics

Let me write this up in a clean, condensed format.</think>

---
type: CommandReference
command: Attribute::Handlers
mode: perldoc
section: 3perl
source: perldoc
---

## Quick Reference

- `use Attribute::Handlers;` — inherit into a package to define attribute handler subroutines
- `sub Name :ATTR { ... }` — define a handler for the `:Name` attribute (all types)
- `sub Name :ATTR(SCALAR) { ... }` — define a type-specific handler
- `sub Name :ATTR(RAWDATA) { ... }` — disable data interpretation, get raw string
- `sub Name :ATTR(SCALAR,BEGIN) { ... }` — control compilation phase when handler runs
- `use Attribute::Handlers autotie => { Attr => 'Tie::Class' };` — auto-create tie interface
- `use Attribute::Handlers autotieref => { Attr => 'Tie::Class' };` — like autotie but passes tied var ref
- `findsym($package, $referent)` — look up typeglob for a variable or subroutine reference

## Name

`Attribute::Handlers` — simpler definition of attribute handlers

## Synopsis

perl
package MyClass;
require 5.006;
use Attribute::Handlers;
no warnings 'redefine';

sub Good : ATTR(SCALAR) {
    my ($package, $symbol, $referent, $attr, $data) = @_;
    # executed in CHECK phase
}

sub Good : ATTR(ARRAY)  { ... }
sub Good : ATTR(HASH)   { ... }
sub Ugly : ATTR(CODE)   { ... }
sub Omni : ATTR         { ... } # any referent type; use ref($_[2])

use Attribute::Handlers autotie => { Cycle => 'Tie::Cycle' };
my $next : Cycle(['A'..'Z']);
## Description

When inherited by a package, allows that package to define attribute handler subroutines. Variables and subroutines subsequently defined in that package (or derived packages) may be given attributes with the same names, and the handlers will be called in a compilation phase: `BEGIN`, `CHECK`, `INIT`, or `END`. `UNITCHECK` blocks do not correspond to a global compilation phase and cannot be specified.

To create a handler, define a subroutine with the same name as the attribute and declare it with `:ATTR`.

### Handler Argument List

| Index | Description |
|-------|-------------|
| `[0]` | Package into which it was declared |
| `[1]` | Reference to symbol table entry (typeglob); `'LEXICAL'` for lexicals, `'ANON'` for anon subs |
| `[2]` | Reference to the variable or subroutine |
| `[3]` | Name of the attribute |
| `[4]` | Data associated with the attribute (arrayref on successful parse, raw string otherwise, `undef` if none) |
| `[5]` | Compilation phase name |
| `[6]` | Filename |
| `[7]` | Line number |

### Data Argument Parsing

The module converts `$_[4]` to a usable form before passing it to the handler. Successful parsing delivers an array reference; failed parsing delivers the raw string.

perl
sub foo :Loud(till=>ears=>are=>bleeding) {...}  # $data = ['till','ears','are','bleeding']
sub foo :Loud(qw/till ears are bleeding/) {...} # $data = ['till','ears','are','bleeding']
sub foo :Loud(['till','ears','are','bleeding']) {...} # $data = [['till','ears','are','bleeding']]
sub foo :Loud(my,ears,are,bleeding) {...}      # $data = 'my,ears,are,bleeding' (raw)
## Options

### Typed Lexicals

Lexicals are routed to the handler of the package they are typed to, regardless of where declared.

perl
package OtherClass;
my LoudDecl $loudobj : Loud;  # invokes LoudDecl::Loud
### Type-Specific Handlers

Specify the referent type in `:ATTR(...)`:

- `:ATTR(SCALAR)`, `:ATTR(ARRAY)`, `:ATTR(HASH)`, `:ATTR(CODE)` — restrict to that type
- `:ATTR(ANY)` — synonym for bare `:ATTR`, handles all types

perl
sub RealLoud :ATTR(SCALAR) { print "Yeeeeow!" }
sub RealLoud :ATTR(ARRAY)  { print "Urrrrrrrrrr!" }
sub RealLoud :ATTR(HASH)   { print "Arrrrrgggghhhhhh!" }
sub RealLoud :ATTR(CODE)   { croak "Real loud sub torpedoed" }
### Non-Interpretive Handlers

Use the `RAWDATA` keyword to disable data parsing; the handler receives the raw string.

perl
sub Raw         : ATTR(RAWDATA)         {...}
sub Nekkid      : ATTR(SCALAR,RAWDATA)  {...}
sub Au::Naturale: ATTR(RAWDATA,ANY)     {...}
my $power : Raw(1..100);  # handler receives "1..100"
### Phase-Specific Handlers

Default phase is `CHECK`. Other phases can be specified:

- `BEGIN` — called immediately when the attribute is detected, before any subsequent `BEGIN` blocks
- `CHECK` — default
- `INIT`
- `END`
- Multiple phases may be combined: `:ATTR(SCALAR,BEGIN,END)`

### Attributes as `tie` Interfaces

perl
use Attribute::Handlers;
use Tie::Cycle;

sub UNIVERSAL::Cycle : ATTR(SCALAR) {
    my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
    $data = [ $data ] unless ref $data eq 'ARRAY';
    tie $$referent, 'Tie::Cycle', $data;
}

my $next : Cycle('A'..'Z');   # $next is now tied
When the tying class expects a flattened list:

perl
sub UNIVERSAL::Cycle : ATTR(SCALAR) {
    my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
    my @data = ref $data eq 'ARRAY' ? @$data : $data;
    tie $$referent, 'Tie::Whatever', @data;
}
The module automates this via `autotie`:

perl
use Attribute::Handlers autotie => { Cycle => 'Tie::Cycle' };
my $next : Cycle(['A'..'Z']);  # wrapped as arrayref because autotie passes a list
The `autotie` value is a hash reference. Keys are attribute names; values are tie classes. The class is auto-loaded. Append import args to the class name:

perl
use Attribute::Handlers autotie => { Dir => 'Tie::Dir qw(DIR_UNLINK)' };
Qualified attribute names install in the qualifier's package:

perl
use Attribute::Handlers autotie => {
    Other::Good         => 'Tie::SecureHash',   # installed in Other::
    Bad                 => 'Tie::Taxes',         # installed in current package
    UNIVERSAL::Ugly     => 'Software::Patent',   # installed everywhere
};
`__CALLER__` is a special qualifier that installs the attribute in the package that imports the defining module (quote it as a string to work around a Perl 5.8 parser bug):

perl
package Tie::Me::Kangaroo::Down::Sport;
use Attribute::Handlers autotie => { '__CALLER__::Roo' => __PACKAGE__ };
### autotieref

`autotieref` works like `autotie` but additionally passes a reference to the tied variable:

perl
use Attribute::Handlers autotieref => { Selfish => 'Tie::Selfish' };
my $var : Selfish(@args);
# equivalent to: tie my $var, 'Tie::Selfish', \$var, @args;
## Utility Functions

- `findsym($package, $referent)` — looks up the typeglob in the symbol table of `$package` for the given referent reference. Returns the typeglob, or `undef` if not found. Memoizes successful lookups.

perl
my $symbol = Attribute::Handlers::findsym($package, $referent);
## Examples

The synopsis `MyClass` exposes handler calls like:

perl
# my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous);
MyClass::Good:ATTR(SCALAR)( 'MyClass', 'LEXICAL', \$slr, 'Good',  undef, 'CHECK' );
MyClass::Bad:ATTR(SCALAR)( 'MyClass', 'LEXICAL', \$slr, 'Bad',   0,      'CHECK' );
MyClass::Omni:ATTR(SCALAR)( 'MyClass','LEXICAL', \$slr, 'Omni', '-vorous', 'CHECK' );

# sub fn :Ugly(sister) :Omni('po',tent()) {...}
MyClass::UGLY:ATTR(CODE)( 'SomeOtherClass', \*SomeOtherClass::fn, \&SomeOtherClass::fn,
                         'Ugly',  'sister',      'CHECK' );
MyClass::Omni:ATTR(CODE)( 'SomeOtherClass', \*SomeOtherClass::fn, \&SomeOtherClass::fn,
                         'Omni',  ['po','acle'], 'CHECK' );
Universal handlers install across all packages:

perl
package Descriptions;
use Attribute::Handlers;
my %name;
sub name { return $name{$_[2]} || *{$_[1]}{NAME} }

sub UNIVERSAL::Name :ATTR     { $name{$_[2]} = $_[4]; }
sub UNIVERSAL::Purpose :ATTR  { print STDERR "Purpose of ", &name, " is $_[4]\n"; }
sub UNIVERSAL::Unit :ATTR     { print STDERR &name, " measured in $_[4]\n"; }
perl
use Descriptions;
my $capacity : Name(capacity)
             : Purpose(to store max storage capacity for files)
             : Unit(Gb);

package Other;
sub foo : Purpose(to foo all data before barring it) { }
## Diagnostics

- **`Bad attribute type: ATTR(%s)`** — handler's type is not `SCALAR`, `ARRAY`, `HASH`, `CODE`, or `ANY`.
- **`Attribute handler %s doesn't handle %s attributes`** — handler was defined for a different referent type.
- **`Declaration of %s attribute in package %s may clash with future reserved word`** — handler name is all-lowercase; use mixed-case names.
- **`Can't have two ATTR specifiers on one subroutine`** — combine all specs into one `ATTR(...)`.
- **`Can't autotie a %s`** — autotie only works for `SCALAR`, `ARRAY`, `HASH`.
- **`Internal error: %s symbol went missing`** — attributed subroutine vanished before its handler ran.
- **`Won't be able to apply END handler`** — `END` handler on a lexical variable may not fire because the variable may be gone by then.

## See Also

- [perl attributes](http://localhost/phpMan.php/perldoc/attributes/markdown)
- [Attribute::Handlers autotie reference](http://localhost/phpMan.php/perldoc/Attribute%3A%3AHandlers/markdown)
- [Tie::Cycle](http://localhost/phpMan.php/perldoc/Tie%3A%3ACycle/markdown)
- [Tie::Hash](http://localhost/phpMan.php/perldoc/Tie%3A%3AHash/markdown), [Tie::Scalar](http://localhost/phpMan.php/perldoc/Tie%3A%3AScalar/markdown), [Tie::Array](http://localhost/phpMan.php/perldoc/Tie%3A%3AArray/markdown)
- [perlmod](http://localhost/phpMan.php/perldoc/perlmod/markdown)

## Author

Damian Conway `<damian@conway.org>`. Maintained by Rafael Garcia-Suarez `<rgarciasuarez@gmail.com>`. CPAN release maintained by Steffen Mueller `<smueller@cpan.org>`.