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