[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/se3-unattended/var/se3/unattended/install/linuxaux/opt/perl/lib/5.10.0/Attribute/ -> Handlers.pm (source)

   1  package Attribute::Handlers;
   2  use 5.006;
   3  use Carp;
   4  use warnings;
   5  use strict;
   6  use vars qw($VERSION $AUTOLOAD);
   7  $VERSION = '0.79';
   8  # $DB::single=1;
   9  
  10  my %symcache;
  11  sub findsym {
  12      my ($pkg, $ref, $type) = @_;
  13      return $symcache{$pkg,$ref} if $symcache{$pkg,$ref};
  14      $type ||= ref($ref);
  15      my $found;
  16      no strict 'refs';
  17          foreach my $sym ( values %{$pkg."::"} ) {
  18          use strict;
  19          next unless ref ( \$sym ) eq 'GLOB';
  20              return $symcache{$pkg,$ref} = \$sym
  21          if *{$sym}{$type} && *{$sym}{$type} == $ref;
  22      }
  23  }
  24  
  25  my %validtype = (
  26      VAR    => [qw[SCALAR ARRAY HASH]],
  27          ANY    => [qw[SCALAR ARRAY HASH CODE]],
  28          ""    => [qw[SCALAR ARRAY HASH CODE]],
  29          SCALAR    => [qw[SCALAR]],
  30          ARRAY    => [qw[ARRAY]],
  31          HASH    => [qw[HASH]],
  32          CODE    => [qw[CODE]],
  33  );
  34  my %lastattr;
  35  my @declarations;
  36  my %raw;
  37  my %phase;
  38  my %sigil = (SCALAR=>'$', ARRAY=>'@', HASH=>'%');
  39  my $global_phase = 0;
  40  my %global_phases = (
  41      BEGIN    => 0,
  42      CHECK    => 1,
  43      INIT    => 2,
  44      END    => 3,
  45  );
  46  my @global_phases = qw(BEGIN CHECK INIT END);
  47  
  48  sub _usage_AH_ {
  49      croak "Usage: use $_[0] autotie => {AttrName => TieClassName,...}";
  50  }
  51  
  52  my $qual_id = qr/^[_a-z]\w*(::[_a-z]\w*)*$/i;
  53  
  54  sub import {
  55      my $class = shift @_;
  56      return unless $class eq "Attribute::Handlers";
  57      while (@_) {
  58      my $cmd = shift;
  59          if ($cmd =~ /^autotie((?:ref)?)$/) {
  60          my $tiedata = ($1 ? '$ref, ' : '') . '@$data';
  61              my $mapping = shift;
  62          _usage_AH_ $class unless ref($mapping) eq 'HASH';
  63          while (my($attr, $tieclass) = each %$mapping) {
  64                  $tieclass =~ s/^([_a-z]\w*(::[_a-z]\w*)*)(.*)/$1/is;
  65          my $args = $3||'()';
  66          _usage_AH_ $class unless $attr =~ $qual_id
  67                           && $tieclass =~ $qual_id
  68                           && eval "use base q\0$tieclass\0; 1";
  69              if ($tieclass->isa('Exporter')) {
  70              local $Exporter::ExportLevel = 2;
  71              $tieclass->import(eval $args);
  72              }
  73          $attr =~ s/__CALLER__/caller(1)/e;
  74          $attr = caller()."::".$attr unless $attr =~ /::/;
  75              eval qq{
  76                  sub $attr : ATTR(VAR) {
  77              my (\$ref, \$data) = \@_[2,4];
  78              my \$was_arrayref = ref \$data eq 'ARRAY';
  79              \$data = [ \$data ] unless \$was_arrayref;
  80              my \$type = ref(\$ref)||"value (".(\$ref||"<undef>").")";
  81               (\$type eq 'SCALAR')? tie \$\$ref,'$tieclass',$tiedata
  82              :(\$type eq 'ARRAY') ? tie \@\$ref,'$tieclass',$tiedata
  83              :(\$type eq 'HASH')  ? tie \%\$ref,'$tieclass',$tiedata
  84              : die "Can't autotie a \$type\n"
  85                  } 1
  86              } or die "Internal error: $@";
  87          }
  88          }
  89          else {
  90              croak "Can't understand $_"; 
  91          }
  92      }
  93  }
  94  sub _resolve_lastattr {
  95      return unless $lastattr{ref};
  96      my $sym = findsym @lastattr{'pkg','ref'}
  97          or die "Internal error: $lastattr{pkg} symbol went missing";
  98      my $name = *{$sym}{NAME};
  99      warn "Declaration of $name attribute in package $lastattr{pkg} may clash with future reserved word\n"
 100          if $^W and $name !~ /[A-Z]/;
 101      foreach ( @{$validtype{$lastattr{type}}} ) {
 102          no strict 'refs';
 103          *{"$lastattr{pkg}::_ATTR_$_}_$name}"} = $lastattr{ref};
 104      }
 105      %lastattr = ();
 106  }
 107  
 108  sub AUTOLOAD {
 109      return if $AUTOLOAD =~ /::DESTROY$/;
 110      my ($class) = $AUTOLOAD =~ m/(.*)::/g;
 111      $AUTOLOAD =~ m/_ATTR_(.*?)_(.*)/ or
 112          croak "Can't locate class method '$AUTOLOAD' via package '$class'";
 113      croak "Attribute handler '$2' doesn't handle $1 attributes";
 114  }
 115  
 116  my $builtin = qr/lvalue|method|locked|unique|shared/;
 117  
 118  sub _gen_handler_AH_() {
 119      return sub {
 120          _resolve_lastattr;
 121          my ($pkg, $ref, @attrs) = @_;
 122          my (undef, $filename, $linenum) = caller 2;
 123          foreach (@attrs) {
 124          my ($attr, $data) = /^([a-z_]\w*)(?:[(](.*)[)])?$/is or next;
 125          if ($attr eq 'ATTR') {
 126              no strict 'refs';
 127              $data ||= "ANY";
 128              $raw{$ref} = $data =~ s/\s*,?\s*RAWDATA\s*,?\s*//;
 129              $phase{$ref}{BEGIN} = 1
 130                  if $data =~ s/\s*,?\s*(BEGIN)\s*,?\s*//;
 131              $phase{$ref}{INIT} = 1
 132                  if $data =~ s/\s*,?\s*(INIT)\s*,?\s*//;
 133              $phase{$ref}{END} = 1
 134                  if $data =~ s/\s*,?\s*(END)\s*,?\s*//;
 135              $phase{$ref}{CHECK} = 1
 136                  if $data =~ s/\s*,?\s*(CHECK)\s*,?\s*//
 137                  || ! keys %{$phase{$ref}};
 138              # Added for cleanup to not pollute next call.
 139              (%lastattr = ()),
 140              croak "Can't have two ATTR specifiers on one subroutine"
 141                  if keys %lastattr;
 142              croak "Bad attribute type: ATTR($data)"
 143                  unless $validtype{$data};
 144              %lastattr=(pkg=>$pkg,ref=>$ref,type=>$data);
 145          }
 146          else {
 147              my $type = ref $ref;
 148              my $handler = $pkg->can("_ATTR_$type}_$attr}");
 149              next unless $handler;
 150                  my $decl = [$pkg, $ref, $attr, $data,
 151                      $raw{$handler}, $phase{$handler}, $filename, $linenum];
 152              foreach my $gphase (@global_phases) {
 153                  _apply_handler_AH_($decl,$gphase)
 154                  if $global_phases{$gphase} <= $global_phase;
 155              }
 156              if ($global_phase != 0) {
 157                  # if _gen_handler_AH_ is being called after 
 158                  # CHECK it's for a lexical, so make sure
 159                  # it didn't want to run anything later
 160              
 161                  local $Carp::CarpLevel = 2;
 162                  carp "Won't be able to apply END handler"
 163                      if $phase{$handler}{END};
 164              }
 165              else {
 166                  push @declarations, $decl
 167              }
 168          }
 169          $_ = undef;
 170          }
 171          return grep {defined && !/$builtin/} @attrs;
 172      }
 173  }
 174  
 175  {
 176      no strict 'refs';
 177      *{"Attribute::Handlers::UNIVERSAL::MODIFY_$_}_ATTRIBUTES"} =
 178      _gen_handler_AH_ foreach @{$validtype{ANY}};
 179  }
 180  push @UNIVERSAL::ISA, 'Attribute::Handlers::UNIVERSAL'
 181         unless grep /^Attribute::Handlers::UNIVERSAL$/, @UNIVERSAL::ISA;
 182  
 183  sub _apply_handler_AH_ {
 184      my ($declaration, $phase) = @_;
 185      my ($pkg, $ref, $attr, $data, $raw, $handlerphase, $filename, $linenum) = @$declaration;
 186      return unless $handlerphase->{$phase};
 187      # print STDERR "Handling $attr on $ref in $phase with [$data]\n";
 188      my $type = ref $ref;
 189      my $handler = "_ATTR_$type}_$attr}";
 190      my $sym = findsym($pkg, $ref);
 191      $sym ||= $type eq 'CODE' ? 'ANON' : 'LEXICAL';
 192      no warnings;
 193      if (!$raw && defined($data)) {
 194          if ($data ne '') {
 195          my $evaled = eval("package $pkg; no warnings; no strict;
 196                     local \$SIG{__WARN__}=sub{die}; [$data]");
 197          $data = $evaled unless $@;
 198          }
 199          else { $data = undef }
 200      }
 201      $pkg->$handler($sym,
 202                 (ref $sym eq 'GLOB' ? *{$sym}{ref $ref}||$ref : $ref),
 203                 $attr,
 204                 $data,
 205                 $phase,
 206                 $filename,
 207                 $linenum,
 208                );
 209      return 1;
 210  }
 211  
 212  {
 213          no warnings 'void';
 214          CHECK {
 215                 $global_phase++;
 216                 _resolve_lastattr;
 217                 _apply_handler_AH_($_,'CHECK') foreach @declarations;
 218          }
 219  
 220          INIT {
 221                  $global_phase++;
 222                  _apply_handler_AH_($_,'INIT') foreach @declarations
 223          }
 224  }
 225  
 226  END { $global_phase++; _apply_handler_AH_($_,'END') foreach @declarations }
 227  
 228  1;
 229  __END__
 230  
 231  =head1 NAME
 232  
 233  Attribute::Handlers - Simpler definition of attribute handlers
 234  
 235  =head1 VERSION
 236  
 237  This document describes version 0.79 of Attribute::Handlers,
 238  released November 25, 2007.
 239  
 240  =head1 SYNOPSIS
 241  
 242      package MyClass;
 243      require v5.6.0;
 244      use Attribute::Handlers;
 245      no warnings 'redefine';
 246  
 247  
 248      sub Good : ATTR(SCALAR) {
 249          my ($package, $symbol, $referent, $attr, $data) = @_;
 250  
 251          # Invoked for any scalar variable with a :Good attribute,
 252          # provided the variable was declared in MyClass (or
 253          # a derived class) or typed to MyClass.
 254  
 255          # Do whatever to $referent here (executed in CHECK phase).
 256          ...
 257      }
 258  
 259      sub Bad : ATTR(SCALAR) {
 260          # Invoked for any scalar variable with a :Bad attribute,
 261          # provided the variable was declared in MyClass (or
 262          # a derived class) or typed to MyClass.
 263          ...
 264      }
 265  
 266      sub Good : ATTR(ARRAY) {
 267          # Invoked for any array variable with a :Good attribute,
 268          # provided the variable was declared in MyClass (or
 269          # a derived class) or typed to MyClass.
 270          ...
 271      }
 272  
 273      sub Good : ATTR(HASH) {
 274          # Invoked for any hash variable with a :Good attribute,
 275          # provided the variable was declared in MyClass (or
 276          # a derived class) or typed to MyClass.
 277          ...
 278      }
 279  
 280      sub Ugly : ATTR(CODE) {
 281          # Invoked for any subroutine declared in MyClass (or a 
 282          # derived class) with an :Ugly attribute.
 283          ...
 284      }
 285  
 286      sub Omni : ATTR {
 287          # Invoked for any scalar, array, hash, or subroutine
 288          # with an :Omni attribute, provided the variable or
 289          # subroutine was declared in MyClass (or a derived class)
 290          # or the variable was typed to MyClass.
 291          # Use ref($_[2]) to determine what kind of referent it was.
 292          ...
 293      }
 294  
 295  
 296      use Attribute::Handlers autotie => { Cycle => Tie::Cycle };
 297  
 298      my $next : Cycle(['A'..'Z']);
 299  
 300  
 301  =head1 DESCRIPTION
 302  
 303  This module, when inherited by a package, allows that package's class to
 304  define attribute handler subroutines for specific attributes. Variables
 305  and subroutines subsequently defined in that package, or in packages
 306  derived from that package may be given attributes with the same names as
 307  the attribute handler subroutines, which will then be called in one of
 308  the compilation phases (i.e. in a C<BEGIN>, C<CHECK>, C<INIT>, or C<END>
 309  block). (C<UNITCHECK> blocks don't correspond to a global compilation
 310  phase, so they can't be specified here.)
 311  
 312  To create a handler, define it as a subroutine with the same name as
 313  the desired attribute, and declare the subroutine itself with the  
 314  attribute C<:ATTR>. For example:
 315  
 316      package LoudDecl;
 317      use Attribute::Handlers;
 318  
 319      sub Loud :ATTR {
 320      my ($package, $symbol, $referent, $attr, $data, $phase, $filename, $linenum) = @_;
 321      print STDERR
 322          ref($referent), " ",
 323          *{$symbol}{NAME}, " ",
 324          "($referent) ", "was just declared ",
 325          "and ascribed the $attr} attribute ",
 326          "with data ($data)\n",
 327          "in phase $phase\n",
 328          "in file $filename at line $linenum\n";
 329      }
 330  
 331  This creates a handler for the attribute C<:Loud> in the class LoudDecl.
 332  Thereafter, any subroutine declared with a C<:Loud> attribute in the class
 333  LoudDecl:
 334  
 335      package LoudDecl;
 336  
 337      sub foo: Loud {...}
 338  
 339  causes the above handler to be invoked, and passed:
 340  
 341  =over
 342  
 343  =item [0]
 344  
 345  the name of the package into which it was declared;
 346  
 347  =item [1]
 348  
 349  a reference to the symbol table entry (typeglob) containing the subroutine;
 350  
 351  =item [2]
 352  
 353  a reference to the subroutine;
 354  
 355  =item [3]
 356  
 357  the name of the attribute;
 358  
 359  =item [4]
 360  
 361  any data associated with that attribute;
 362  
 363  =item [5]
 364  
 365  the name of the phase in which the handler is being invoked;
 366  
 367  =item [6]
 368  
 369  the filename in which the handler is being invoked;
 370  
 371  =item [7]
 372  
 373  the line number in this file.
 374  
 375  =back
 376  
 377  Likewise, declaring any variables with the C<:Loud> attribute within the
 378  package:
 379  
 380          package LoudDecl;
 381  
 382          my $foo :Loud;
 383          my @foo :Loud;
 384          my %foo :Loud;
 385  
 386  will cause the handler to be called with a similar argument list (except,
 387  of course, that C<$_[2]> will be a reference to the variable).
 388  
 389  The package name argument will typically be the name of the class into
 390  which the subroutine was declared, but it may also be the name of a derived
 391  class (since handlers are inherited).
 392  
 393  If a lexical variable is given an attribute, there is no symbol table to 
 394  which it belongs, so the symbol table argument (C<$_[1]>) is set to the
 395  string C<'LEXICAL'> in that case. Likewise, ascribing an attribute to
 396  an anonymous subroutine results in a symbol table argument of C<'ANON'>.
 397  
 398  The data argument passes in the value (if any) associated with the
 399  attribute. For example, if C<&foo> had been declared:
 400  
 401          sub foo :Loud("turn it up to 11, man!") {...}
 402  
 403  then a reference to an array containing the string
 404  C<"turn it up to 11, man!"> would be passed as the last argument.
 405  
 406  Attribute::Handlers makes strenuous efforts to convert
 407  the data argument (C<$_[4]>) to a useable form before passing it to
 408  the handler (but see L<"Non-interpretive attribute handlers">).
 409  If those efforts succeed, the interpreted data is passed in an array
 410  reference; if they fail, the raw data is passed as a string.
 411  For example, all of these:
 412  
 413      sub foo :Loud(till=>ears=>are=>bleeding) {...}
 414      sub foo :Loud(qw/till ears are bleeding/) {...}
 415      sub foo :Loud(qw/my, ears, are, bleeding/) {...}
 416      sub foo :Loud(till,ears,are,bleeding) {...}
 417  
 418  causes it to pass C<['till','ears','are','bleeding']> as the handler's
 419  data argument. While:
 420  
 421      sub foo :Loud(['till','ears','are','bleeding']) {...}
 422  
 423  causes it to pass C<[ ['till','ears','are','bleeding'] ]>; the array
 424  reference specified in the data being passed inside the standard
 425  array reference indicating successful interpretation.
 426  
 427  However, if the data can't be parsed as valid Perl, then
 428  it is passed as an uninterpreted string. For example:
 429  
 430      sub foo :Loud(my,ears,are,bleeding) {...}
 431      sub foo :Loud(qw/my ears are bleeding) {...}
 432  
 433  cause the strings C<'my,ears,are,bleeding'> and
 434  C<'qw/my ears are bleeding'> respectively to be passed as the
 435  data argument.
 436  
 437  If no value is associated with the attribute, C<undef> is passed.
 438  
 439  =head2 Typed lexicals
 440  
 441  Regardless of the package in which it is declared, if a lexical variable is
 442  ascribed an attribute, the handler that is invoked is the one belonging to
 443  the package to which it is typed. For example, the following declarations:
 444  
 445          package OtherClass;
 446  
 447          my LoudDecl $loudobj : Loud;
 448          my LoudDecl @loudobjs : Loud;
 449          my LoudDecl %loudobjex : Loud;
 450  
 451  causes the LoudDecl::Loud handler to be invoked (even if OtherClass also
 452  defines a handler for C<:Loud> attributes).
 453  
 454  
 455  =head2 Type-specific attribute handlers
 456  
 457  If an attribute handler is declared and the C<:ATTR> specifier is
 458  given the name of a built-in type (C<SCALAR>, C<ARRAY>, C<HASH>, or C<CODE>),
 459  the handler is only applied to declarations of that type. For example,
 460  the following definition:
 461  
 462          package LoudDecl;
 463  
 464          sub RealLoud :ATTR(SCALAR) { print "Yeeeeow!" }
 465  
 466  creates an attribute handler that applies only to scalars:
 467  
 468  
 469          package Painful;
 470          use base LoudDecl;
 471  
 472          my $metal : RealLoud;           # invokes &LoudDecl::RealLoud
 473          my @metal : RealLoud;           # error: unknown attribute
 474          my %metal : RealLoud;           # error: unknown attribute
 475          sub metal : RealLoud {...}      # error: unknown attribute
 476  
 477  You can, of course, declare separate handlers for these types as well
 478  (but you'll need to specify C<no warnings 'redefine'> to do it quietly):
 479  
 480          package LoudDecl;
 481          use Attribute::Handlers;
 482          no warnings 'redefine';
 483  
 484          sub RealLoud :ATTR(SCALAR) { print "Yeeeeow!" }
 485          sub RealLoud :ATTR(ARRAY) { print "Urrrrrrrrrr!" }
 486          sub RealLoud :ATTR(HASH) { print "Arrrrrgggghhhhhh!" }
 487          sub RealLoud :ATTR(CODE) { croak "Real loud sub torpedoed" }
 488  
 489  You can also explicitly indicate that a single handler is meant to be
 490  used for all types of referents like so:
 491  
 492          package LoudDecl;
 493          use Attribute::Handlers;
 494  
 495          sub SeriousLoud :ATTR(ANY) { warn "Hearing loss imminent" }
 496  
 497  (I.e. C<ATTR(ANY)> is a synonym for C<:ATTR>).
 498  
 499  
 500  =head2 Non-interpretive attribute handlers
 501  
 502  Occasionally the strenuous efforts Attribute::Handlers makes to convert
 503  the data argument (C<$_[4]>) to a useable form before passing it to
 504  the handler get in the way.
 505  
 506  You can turn off that eagerness-to-help by declaring
 507  an attribute handler with the keyword C<RAWDATA>. For example:
 508  
 509          sub Raw          : ATTR(RAWDATA) {...}
 510          sub Nekkid       : ATTR(SCALAR,RAWDATA) {...}
 511          sub Au::Naturale : ATTR(RAWDATA,ANY) {...}
 512  
 513  Then the handler makes absolutely no attempt to interpret the data it
 514  receives and simply passes it as a string:
 515  
 516          my $power : Raw(1..100);        # handlers receives "1..100"
 517  
 518  =head2 Phase-specific attribute handlers
 519  
 520  By default, attribute handlers are called at the end of the compilation
 521  phase (in a C<CHECK> block). This seems to be optimal in most cases because
 522  most things that can be defined are defined by that point but nothing has
 523  been executed.
 524  
 525  However, it is possible to set up attribute handlers that are called at
 526  other points in the program's compilation or execution, by explicitly
 527  stating the phase (or phases) in which you wish the attribute handler to
 528  be called. For example:
 529  
 530          sub Early    :ATTR(SCALAR,BEGIN) {...}
 531          sub Normal   :ATTR(SCALAR,CHECK) {...}
 532          sub Late     :ATTR(SCALAR,INIT) {...}
 533          sub Final    :ATTR(SCALAR,END) {...}
 534          sub Bookends :ATTR(SCALAR,BEGIN,END) {...}
 535  
 536  As the last example indicates, a handler may be set up to be (re)called in
 537  two or more phases. The phase name is passed as the handler's final argument.
 538  
 539  Note that attribute handlers that are scheduled for the C<BEGIN> phase
 540  are handled as soon as the attribute is detected (i.e. before any
 541  subsequently defined C<BEGIN> blocks are executed).
 542  
 543  
 544  =head2 Attributes as C<tie> interfaces
 545  
 546  Attributes make an excellent and intuitive interface through which to tie
 547  variables. For example:
 548  
 549          use Attribute::Handlers;
 550          use Tie::Cycle;
 551  
 552          sub UNIVERSAL::Cycle : ATTR(SCALAR) {
 553                  my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
 554                  $data = [ $data ] unless ref $data eq 'ARRAY';
 555                  tie $$referent, 'Tie::Cycle', $data;
 556          }
 557  
 558          # and thereafter...
 559  
 560          package main;
 561  
 562          my $next : Cycle('A'..'Z');     # $next is now a tied variable
 563  
 564          while (<>) {
 565                  print $next;
 566          }
 567  
 568  Note that, because the C<Cycle> attribute receives its arguments in the
 569  C<$data> variable, if the attribute is given a list of arguments, C<$data>
 570  will consist of a single array reference; otherwise, it will consist of the
 571  single argument directly. Since Tie::Cycle requires its cycling values to
 572  be passed as an array reference, this means that we need to wrap
 573  non-array-reference arguments in an array constructor:
 574  
 575          $data = [ $data ] unless ref $data eq 'ARRAY';
 576  
 577  Typically, however, things are the other way around: the tieable class expects
 578  its arguments as a flattened list, so the attribute looks like:
 579  
 580          sub UNIVERSAL::Cycle : ATTR(SCALAR) {
 581                  my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
 582                  my @data = ref $data eq 'ARRAY' ? @$data : $data;
 583                  tie $$referent, 'Tie::Whatever', @data;
 584          }
 585  
 586  
 587  This software pattern is so widely applicable that Attribute::Handlers
 588  provides a way to automate it: specifying C<'autotie'> in the
 589  C<use Attribute::Handlers> statement. So, the cycling example,
 590  could also be written:
 591  
 592          use Attribute::Handlers autotie => { Cycle => 'Tie::Cycle' };
 593  
 594          # and thereafter...
 595  
 596          package main;
 597  
 598          my $next : Cycle(['A'..'Z']);     # $next is now a tied variable
 599  
 600          while (<>) {
 601                  print $next;
 602  
 603  Note that we now have to pass the cycling values as an array reference,
 604  since the C<autotie> mechanism passes C<tie> a list of arguments as a list
 605  (as in the Tie::Whatever example), I<not> as an array reference (as in
 606  the original Tie::Cycle example at the start of this section).
 607  
 608  The argument after C<'autotie'> is a reference to a hash in which each key is
 609  the name of an attribute to be created, and each value is the class to which
 610  variables ascribed that attribute should be tied.
 611  
 612  Note that there is no longer any need to import the Tie::Cycle module --
 613  Attribute::Handlers takes care of that automagically. You can even pass
 614  arguments to the module's C<import> subroutine, by appending them to the
 615  class name. For example:
 616  
 617      use Attribute::Handlers
 618          autotie => { Dir => 'Tie::Dir qw(DIR_UNLINK)' };
 619  
 620  If the attribute name is unqualified, the attribute is installed in the
 621  current package. Otherwise it is installed in the qualifier's package:
 622  
 623          package Here;
 624  
 625          use Attribute::Handlers autotie => {
 626                  Other::Good => Tie::SecureHash, # tie attr installed in Other::
 627                          Bad => Tie::Taxes,      # tie attr installed in Here::
 628              UNIVERSAL::Ugly => Software::Patent # tie attr installed everywhere
 629          };
 630  
 631  Autoties are most commonly used in the module to which they actually tie, 
 632  and need to export their attributes to any module that calls them. To
 633  facilitate this, Attribute::Handlers recognizes a special "pseudo-class" --
 634  C<__CALLER__>, which may be specified as the qualifier of an attribute:
 635  
 636          package Tie::Me::Kangaroo:Down::Sport;
 637  
 638          use Attribute::Handlers autotie => { '__CALLER__::Roo' => __PACKAGE__ };
 639  
 640  This causes Attribute::Handlers to define the C<Roo> attribute in the package
 641  that imports the Tie::Me::Kangaroo:Down::Sport module.
 642  
 643  Note that it is important to quote the __CALLER__::Roo identifier because
 644  a bug in perl 5.8 will refuse to parse it and cause an unknown error.
 645  
 646  =head3 Passing the tied object to C<tie>
 647  
 648  Occasionally it is important to pass a reference to the object being tied
 649  to the TIESCALAR, TIEHASH, etc. that ties it. 
 650  
 651  The C<autotie> mechanism supports this too. The following code:
 652  
 653      use Attribute::Handlers autotieref => { Selfish => Tie::Selfish };
 654      my $var : Selfish(@args);
 655  
 656  has the same effect as:
 657  
 658      tie my $var, 'Tie::Selfish', @args;
 659  
 660  But when C<"autotieref"> is used instead of C<"autotie">:
 661  
 662      use Attribute::Handlers autotieref => { Selfish => Tie::Selfish };
 663      my $var : Selfish(@args);
 664  
 665  the effect is to pass the C<tie> call an extra reference to the variable
 666  being tied:
 667  
 668          tie my $var, 'Tie::Selfish', \$var, @args;
 669  
 670  
 671  
 672  =head1 EXAMPLES
 673  
 674  If the class shown in L<SYNOPSIS> were placed in the MyClass.pm
 675  module, then the following code:
 676  
 677          package main;
 678          use MyClass;
 679  
 680          my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous);
 681  
 682          package SomeOtherClass;
 683          use base MyClass;
 684  
 685          sub tent { 'acle' }
 686  
 687          sub fn :Ugly(sister) :Omni('po',tent()) {...}
 688          my @arr :Good :Omni(s/cie/nt/);
 689          my %hsh :Good(q/bye) :Omni(q/bus/);
 690  
 691  
 692  would cause the following handlers to be invoked:
 693  
 694          # my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous);
 695  
 696          MyClass::Good:ATTR(SCALAR)( 'MyClass',          # class
 697                                      'LEXICAL',          # no typeglob
 698                                      \$slr,              # referent
 699                                      'Good',             # attr name
 700                                      undef               # no attr data
 701                                      'CHECK',            # compiler phase
 702                                    );
 703  
 704          MyClass::Bad:ATTR(SCALAR)( 'MyClass',           # class
 705                                     'LEXICAL',           # no typeglob
 706                                     \$slr,               # referent
 707                                     'Bad',               # attr name
 708                                     0                    # eval'd attr data
 709                                     'CHECK',             # compiler phase
 710                                   );
 711  
 712          MyClass::Omni:ATTR(SCALAR)( 'MyClass',          # class
 713                                      'LEXICAL',          # no typeglob
 714                                      \$slr,              # referent
 715                                      'Omni',             # attr name
 716                                      '-vorous'           # eval'd attr data
 717                                      'CHECK',            # compiler phase
 718                                    );
 719  
 720  
 721          # sub fn :Ugly(sister) :Omni('po',tent()) {...}
 722  
 723          MyClass::UGLY:ATTR(CODE)( 'SomeOtherClass',     # class
 724                                    \*SomeOtherClass::fn, # typeglob
 725                                    \&SomeOtherClass::fn, # referent
 726                                    'Ugly',               # attr name
 727                                    'sister'              # eval'd attr data
 728                                    'CHECK',              # compiler phase
 729                                  );
 730  
 731          MyClass::Omni:ATTR(CODE)( 'SomeOtherClass',     # class
 732                                    \*SomeOtherClass::fn, # typeglob
 733                                    \&SomeOtherClass::fn, # referent
 734                                    'Omni',               # attr name
 735                                    ['po','acle']         # eval'd attr data
 736                                    'CHECK',              # compiler phase
 737                                  );
 738  
 739  
 740          # my @arr :Good :Omni(s/cie/nt/);
 741  
 742          MyClass::Good:ATTR(ARRAY)( 'SomeOtherClass',    # class
 743                                     'LEXICAL',           # no typeglob
 744                                     \@arr,               # referent
 745                                     'Good',              # attr name
 746                                     undef                # no attr data
 747                                     'CHECK',             # compiler phase
 748                                   );
 749  
 750          MyClass::Omni:ATTR(ARRAY)( 'SomeOtherClass',    # class
 751                                     'LEXICAL',           # no typeglob
 752                                     \@arr,               # referent
 753                                     'Omni',              # attr name
 754                                     ""                   # eval'd attr data 
 755                                     'CHECK',             # compiler phase
 756                                   );
 757  
 758  
 759          # my %hsh :Good(q/bye) :Omni(q/bus/);
 760                                    
 761          MyClass::Good:ATTR(HASH)( 'SomeOtherClass',     # class
 762                                    'LEXICAL',            # no typeglob
 763                                    \%hsh,                # referent
 764                                    'Good',               # attr name
 765                                    'q/bye'               # raw attr data
 766                                    'CHECK',              # compiler phase
 767                                  );
 768                          
 769          MyClass::Omni:ATTR(HASH)( 'SomeOtherClass',     # class
 770                                    'LEXICAL',            # no typeglob
 771                                    \%hsh,                # referent
 772                                    'Omni',               # attr name
 773                                    'bus'                 # eval'd attr data
 774                                    'CHECK',              # compiler phase
 775                                  );
 776  
 777  
 778  Installing handlers into UNIVERSAL, makes them...err..universal.
 779  For example:
 780  
 781          package Descriptions;
 782          use Attribute::Handlers;
 783  
 784          my %name;
 785          sub name { return $name{$_[2]}||*{$_[1]}{NAME} }
 786  
 787          sub UNIVERSAL::Name :ATTR {
 788                  $name{$_[2]} = $_[4];
 789          }
 790  
 791          sub UNIVERSAL::Purpose :ATTR {
 792                  print STDERR "Purpose of ", &name, " is $_[4]\n";
 793          }
 794  
 795          sub UNIVERSAL::Unit :ATTR {
 796                  print STDERR &name, " measured in $_[4]\n";
 797          }
 798  
 799  Let's you write:
 800  
 801          use Descriptions;
 802  
 803          my $capacity : Name(capacity)
 804                       : Purpose(to store max storage capacity for files)
 805                       : Unit(Gb);
 806  
 807  
 808          package Other;
 809  
 810          sub foo : Purpose(to foo all data before barring it) { }
 811  
 812          # etc.
 813  
 814  
 815  =head1 DIAGNOSTICS
 816  
 817  =over
 818  
 819  =item C<Bad attribute type: ATTR(%s)>
 820  
 821  An attribute handler was specified with an C<:ATTR(I<ref_type>)>, but the
 822  type of referent it was defined to handle wasn't one of the five permitted:
 823  C<SCALAR>, C<ARRAY>, C<HASH>, C<CODE>, or C<ANY>.
 824  
 825  =item C<Attribute handler %s doesn't handle %s attributes>
 826  
 827  A handler for attributes of the specified name I<was> defined, but not
 828  for the specified type of declaration. Typically encountered whe trying
 829  to apply a C<VAR> attribute handler to a subroutine, or a C<SCALAR>
 830  attribute handler to some other type of variable.
 831  
 832  =item C<Declaration of %s attribute in package %s may clash with future reserved word>
 833  
 834  A handler for an attributes with an all-lowercase name was declared. An
 835  attribute with an all-lowercase name might have a meaning to Perl
 836  itself some day, even though most don't yet. Use a mixed-case attribute
 837  name, instead.
 838  
 839  =item C<Can't have two ATTR specifiers on one subroutine>
 840  
 841  You just can't, okay?
 842  Instead, put all the specifications together with commas between them
 843  in a single C<ATTR(I<specification>)>.
 844  
 845  =item C<Can't autotie a %s>
 846  
 847  You can only declare autoties for types C<"SCALAR">, C<"ARRAY">, and
 848  C<"HASH">. They're the only things (apart from typeglobs -- which are
 849  not declarable) that Perl can tie.
 850  
 851  =item C<Internal error: %s symbol went missing>
 852  
 853  Something is rotten in the state of the program. An attributed
 854  subroutine ceased to exist between the point it was declared and the point
 855  at which its attribute handler(s) would have been called.
 856  
 857  =item C<Won't be able to apply END handler>
 858  
 859  You have defined an END handler for an attribute that is being applied
 860  to a lexical variable.  Since the variable may not be available during END
 861  this won't happen.
 862  
 863  =back
 864  
 865  =head1 AUTHOR
 866  
 867  Damian Conway (damian@conway.org)
 868  
 869  =head1 BUGS
 870  
 871  There are undoubtedly serious bugs lurking somewhere in code this funky :-)
 872  Bug reports and other feedback are most welcome.
 873  
 874  =head1 COPYRIGHT
 875  
 876           Copyright (c) 2001, Damian Conway. All Rights Reserved.
 877         This module is free software. It may be used, redistributed
 878             and/or modified under the same terms as Perl itself.


Generated: Tue Mar 17 22:47:18 2015 Cross-referenced by PHPXref 0.7.1