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