1Attribute::Handlers(3pm)Perl Programmers Reference GuideAttribute::Handlers(3pm)
2
3
4
6 Attribute::Handlers - Simpler definition of attribute handlers
7
9 This document describes version 0.78 of Attribute::Handlers, released
10 October 5, 2002.
11
13 package MyClass;
14 require v5.6.0;
15 use Attribute::Handlers;
16 no warnings 'redefine';
17
18 sub Good : ATTR(SCALAR) {
19 my ($package, $symbol, $referent, $attr, $data) = @_;
20
21 # Invoked for any scalar variable with a :Good attribute,
22 # provided the variable was declared in MyClass (or
23 # a derived class) or typed to MyClass.
24
25 # Do whatever to $referent here (executed in CHECK phase).
26 ...
27 }
28
29 sub Bad : ATTR(SCALAR) {
30 # Invoked for any scalar variable with a :Bad attribute,
31 # provided the variable was declared in MyClass (or
32 # a derived class) or typed to MyClass.
33 ...
34 }
35
36 sub Good : ATTR(ARRAY) {
37 # Invoked for any array variable with a :Good attribute,
38 # provided the variable was declared in MyClass (or
39 # a derived class) or typed to MyClass.
40 ...
41 }
42
43 sub Good : ATTR(HASH) {
44 # Invoked for any hash variable with a :Good attribute,
45 # provided the variable was declared in MyClass (or
46 # a derived class) or typed to MyClass.
47 ...
48 }
49
50 sub Ugly : ATTR(CODE) {
51 # Invoked for any subroutine declared in MyClass (or a
52 # derived class) with an :Ugly attribute.
53 ...
54 }
55
56 sub Omni : ATTR {
57 # Invoked for any scalar, array, hash, or subroutine
58 # with an :Omni attribute, provided the variable or
59 # subroutine was declared in MyClass (or a derived class)
60 # or the variable was typed to MyClass.
61 # Use ref($_[2]) to determine what kind of referent it was.
62 ...
63 }
64
65 use Attribute::Handlers autotie => { Cycle => Tie::Cycle };
66
67 my $next : Cycle(['A'..'Z']);
68
70 This module, when inherited by a package, allows that package's class
71 to define attribute handler subroutines for specific attributes. Vari‐
72 ables and subroutines subsequently defined in that package, or in pack‐
73 ages derived from that package may be given attributes with the same
74 names as the attribute handler subroutines, which will then be called
75 in one of the compilation phases (i.e. in a "BEGIN", "CHECK", "INIT",
76 or "END" block).
77
78 To create a handler, define it as a subroutine with the same name as
79 the desired attribute, and declare the subroutine itself with the
80 attribute ":ATTR". For example:
81
82 package LoudDecl;
83 use Attribute::Handlers;
84
85 sub Loud :ATTR {
86 my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
87 print STDERR
88 ref($referent), " ",
89 *{$symbol}{NAME}, " ",
90 "($referent) ", "was just declared ",
91 "and ascribed the ${attr} attribute ",
92 "with data ($data)\n",
93 "in phase $phase\n";
94 }
95
96 This creates a handler for the attribute ":Loud" in the class LoudDecl.
97 Thereafter, any subroutine declared with a ":Loud" attribute in the
98 class LoudDecl:
99
100 package LoudDecl;
101
102 sub foo: Loud {...}
103
104 causes the above handler to be invoked, and passed:
105
106 [0] the name of the package into which it was declared;
107
108 [1] a reference to the symbol table entry (typeglob) containing the
109 subroutine;
110
111 [2] a reference to the subroutine;
112
113 [3] the name of the attribute;
114
115 [4] any data associated with that attribute;
116
117 [5] the name of the phase in which the handler is being invoked.
118
119 Likewise, declaring any variables with the ":Loud" attribute within the
120 package:
121
122 package LoudDecl;
123
124 my $foo :Loud;
125 my @foo :Loud;
126 my %foo :Loud;
127
128 will cause the handler to be called with a similar argument list
129 (except, of course, that $_[2] will be a reference to the variable).
130
131 The package name argument will typically be the name of the class into
132 which the subroutine was declared, but it may also be the name of a
133 derived class (since handlers are inherited).
134
135 If a lexical variable is given an attribute, there is no symbol table
136 to which it belongs, so the symbol table argument ($_[1]) is set to the
137 string 'LEXICAL' in that case. Likewise, ascribing an attribute to an
138 anonymous subroutine results in a symbol table argument of 'ANON'.
139
140 The data argument passes in the value (if any) associated with the
141 attribute. For example, if &foo had been declared:
142
143 sub foo :Loud("turn it up to 11, man!") {...}
144
145 then the string "turn it up to 11, man!" would be passed as the last
146 argument.
147
148 Attribute::Handlers makes strenuous efforts to convert the data argu‐
149 ment ($_[4]) to a useable form before passing it to the handler (but
150 see "Non-interpretive attribute handlers"). For example, all of these:
151
152 sub foo :Loud(till=>ears=>are=>bleeding) {...}
153 sub foo :Loud(['till','ears','are','bleeding']) {...}
154 sub foo :Loud(qw/till ears are bleeding/) {...}
155 sub foo :Loud(qw/my, ears, are, bleeding/) {...}
156 sub foo :Loud(till,ears,are,bleeding) {...}
157
158 causes it to pass "['till','ears','are','bleeding']" as the handler's
159 data argument. However, if the data can't be parsed as valid Perl, then
160 it is passed as an uninterpreted string. For example:
161
162 sub foo :Loud(my,ears,are,bleeding) {...}
163 sub foo :Loud(qw/my ears are bleeding) {...}
164
165 cause the strings 'my,ears,are,bleeding' and 'qw/my ears are bleeding'
166 respectively to be passed as the data argument.
167
168 If the attribute has only a single associated scalar data value, that
169 value is passed as a scalar. If multiple values are associated, they
170 are passed as an array reference. If no value is associated with the
171 attribute, "undef" is passed.
172
173 Typed lexicals
174
175 Regardless of the package in which it is declared, if a lexical vari‐
176 able is ascribed an attribute, the handler that is invoked is the one
177 belonging to the package to which it is typed. For example, the follow‐
178 ing declarations:
179
180 package OtherClass;
181
182 my LoudDecl $loudobj : Loud;
183 my LoudDecl @loudobjs : Loud;
184 my LoudDecl %loudobjex : Loud;
185
186 causes the LoudDecl::Loud handler to be invoked (even if OtherClass
187 also defines a handler for ":Loud" attributes).
188
189 Type-specific attribute handlers
190
191 If an attribute handler is declared and the ":ATTR" specifier is given
192 the name of a built-in type ("SCALAR", "ARRAY", "HASH", or "CODE"), the
193 handler is only applied to declarations of that type. For example, the
194 following definition:
195
196 package LoudDecl;
197
198 sub RealLoud :ATTR(SCALAR) { print "Yeeeeow!" }
199
200 creates an attribute handler that applies only to scalars:
201
202 package Painful;
203 use base LoudDecl;
204
205 my $metal : RealLoud; # invokes &LoudDecl::RealLoud
206 my @metal : RealLoud; # error: unknown attribute
207 my %metal : RealLoud; # error: unknown attribute
208 sub metal : RealLoud {...} # error: unknown attribute
209
210 You can, of course, declare separate handlers for these types as well
211 (but you'll need to specify "no warnings 'redefine'" to do it quietly):
212
213 package LoudDecl;
214 use Attribute::Handlers;
215 no warnings 'redefine';
216
217 sub RealLoud :ATTR(SCALAR) { print "Yeeeeow!" }
218 sub RealLoud :ATTR(ARRAY) { print "Urrrrrrrrrr!" }
219 sub RealLoud :ATTR(HASH) { print "Arrrrrgggghhhhhh!" }
220 sub RealLoud :ATTR(CODE) { croak "Real loud sub torpedoed" }
221
222 You can also explicitly indicate that a single handler is meant to be
223 used for all types of referents like so:
224
225 package LoudDecl;
226 use Attribute::Handlers;
227
228 sub SeriousLoud :ATTR(ANY) { warn "Hearing loss imminent" }
229
230 (I.e. "ATTR(ANY)" is a synonym for ":ATTR").
231
232 Non-interpretive attribute handlers
233
234 Occasionally the strenuous efforts Attribute::Handlers makes to convert
235 the data argument ($_[4]) to a useable form before passing it to the
236 handler get in the way.
237
238 You can turn off that eagerness-to-help by declaring an attribute han‐
239 dler with the keyword "RAWDATA". For example:
240
241 sub Raw : ATTR(RAWDATA) {...}
242 sub Nekkid : ATTR(SCALAR,RAWDATA) {...}
243 sub Au::Naturale : ATTR(RAWDATA,ANY) {...}
244
245 Then the handler makes absolutely no attempt to interpret the data it
246 receives and simply passes it as a string:
247
248 my $power : Raw(1..100); # handlers receives "1..100"
249
250 Phase-specific attribute handlers
251
252 By default, attribute handlers are called at the end of the compilation
253 phase (in a "CHECK" block). This seems to be optimal in most cases
254 because most things that can be defined are defined by that point but
255 nothing has been executed.
256
257 However, it is possible to set up attribute handlers that are called at
258 other points in the program's compilation or execution, by explicitly
259 stating the phase (or phases) in which you wish the attribute handler
260 to be called. For example:
261
262 sub Early :ATTR(SCALAR,BEGIN) {...}
263 sub Normal :ATTR(SCALAR,CHECK) {...}
264 sub Late :ATTR(SCALAR,INIT) {...}
265 sub Final :ATTR(SCALAR,END) {...}
266 sub Bookends :ATTR(SCALAR,BEGIN,END) {...}
267
268 As the last example indicates, a handler may be set up to be (re)called
269 in two or more phases. The phase name is passed as the handler's final
270 argument.
271
272 Note that attribute handlers that are scheduled for the "BEGIN" phase
273 are handled as soon as the attribute is detected (i.e. before any sub‐
274 sequently defined "BEGIN" blocks are executed).
275
276 Attributes as "tie" interfaces
277
278 Attributes make an excellent and intuitive interface through which to
279 tie variables. For example:
280
281 use Attribute::Handlers;
282 use Tie::Cycle;
283
284 sub UNIVERSAL::Cycle : ATTR(SCALAR) {
285 my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
286 $data = [ $data ] unless ref $data eq 'ARRAY';
287 tie $$referent, 'Tie::Cycle', $data;
288 }
289
290 # and thereafter...
291
292 package main;
293
294 my $next : Cycle('A'..'Z'); # $next is now a tied variable
295
296 while (<>) {
297 print $next;
298 }
299
300 Note that, because the "Cycle" attribute receives its arguments in the
301 $data variable, if the attribute is given a list of arguments, $data
302 will consist of a single array reference; otherwise, it will consist of
303 the single argument directly. Since Tie::Cycle requires its cycling
304 values to be passed as an array reference, this means that we need to
305 wrap non-array-reference arguments in an array constructor:
306
307 $data = [ $data ] unless ref $data eq 'ARRAY';
308
309 Typically, however, things are the other way around: the tieable class
310 expects its arguments as a flattened list, so the attribute looks like:
311
312 sub UNIVERSAL::Cycle : ATTR(SCALAR) {
313 my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
314 my @data = ref $data eq 'ARRAY' ? @$data : $data;
315 tie $$referent, 'Tie::Whatever', @data;
316 }
317
318 This software pattern is so widely applicable that Attribute::Handlers
319 provides a way to automate it: specifying 'autotie' in the "use
320 Attribute::Handlers" statement. So, the cycling example, could also be
321 written:
322
323 use Attribute::Handlers autotie => { Cycle => 'Tie::Cycle' };
324
325 # and thereafter...
326
327 package main;
328
329 my $next : Cycle(['A'..'Z']); # $next is now a tied variable
330
331 while (<>) {
332 print $next;
333
334 Note that we now have to pass the cycling values as an array reference,
335 since the "autotie" mechanism passes "tie" a list of arguments as a
336 list (as in the Tie::Whatever example), not as an array reference (as
337 in the original Tie::Cycle example at the start of this section).
338
339 The argument after 'autotie' is a reference to a hash in which each key
340 is the name of an attribute to be created, and each value is the class
341 to which variables ascribed that attribute should be tied.
342
343 Note that there is no longer any need to import the Tie::Cycle module
344 -- Attribute::Handlers takes care of that automagically. You can even
345 pass arguments to the module's "import" subroutine, by appending them
346 to the class name. For example:
347
348 use Attribute::Handlers
349 autotie => { Dir => 'Tie::Dir qw(DIR_UNLINK)' };
350
351 If the attribute name is unqualified, the attribute is installed in the
352 current package. Otherwise it is installed in the qualifier's package:
353
354 package Here;
355
356 use Attribute::Handlers autotie => {
357 Other::Good => Tie::SecureHash, # tie attr installed in Other::
358 Bad => Tie::Taxes, # tie attr installed in Here::
359 UNIVERSAL::Ugly => Software::Patent # tie attr installed everywhere
360 };
361
362 Autoties are most commonly used in the module to which they actually
363 tie, and need to export their attributes to any module that calls them.
364 To facilitate this, Attribute::Handlers recognizes a special
365 "pseudo-class" -- "__CALLER__", which may be specified as the qualifier
366 of an attribute:
367
368 package Tie::Me::Kangaroo:Down::Sport;
369
370 use Attribute::Handlers autotie => { '__CALLER__::Roo' => __PACKAGE__ };
371
372 This causes Attribute::Handlers to define the "Roo" attribute in the
373 package that imports the Tie::Me::Kangaroo:Down::Sport module.
374
375 Note that it is important to quote the __CALLER__::Roo identifier
376 because a bug in perl 5.8 will refuse to parse it and cause an unknown
377 error.
378
379 Passing the tied object to "tie"
380
381 Occasionally it is important to pass a reference to the object being
382 tied to the TIESCALAR, TIEHASH, etc. that ties it.
383
384 The "autotie" mechanism supports this too. The following code:
385
386 use Attribute::Handlers autotieref => { Selfish => Tie::Selfish };
387 my $var : Selfish(@args);
388
389 has the same effect as:
390
391 tie my $var, 'Tie::Selfish', @args;
392
393 But when "autotieref" is used instead of "autotie":
394
395 use Attribute::Handlers autotieref => { Selfish => Tie::Selfish };
396 my $var : Selfish(@args);
397
398 the effect is to pass the "tie" call an extra reference to the variable
399 being tied:
400
401 tie my $var, 'Tie::Selfish', \$var, @args;
402
404 If the class shown in SYNOPSIS were placed in the MyClass.pm module,
405 then the following code:
406
407 package main;
408 use MyClass;
409
410 my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous);
411
412 package SomeOtherClass;
413 use base MyClass;
414
415 sub tent { 'acle' }
416
417 sub fn :Ugly(sister) :Omni('po',tent()) {...}
418 my @arr :Good :Omni(s/cie/nt/);
419 my %hsh :Good(q/bye) :Omni(q/bus/);
420
421 would cause the following handlers to be invoked:
422
423 # my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous);
424
425 MyClass::Good:ATTR(SCALAR)( 'MyClass', # class
426 'LEXICAL', # no typeglob
427 \$slr, # referent
428 'Good', # attr name
429 undef # no attr data
430 'CHECK', # compiler phase
431 );
432
433 MyClass::Bad:ATTR(SCALAR)( 'MyClass', # class
434 'LEXICAL', # no typeglob
435 \$slr, # referent
436 'Bad', # attr name
437 0 # eval'd attr data
438 'CHECK', # compiler phase
439 );
440
441 MyClass::Omni:ATTR(SCALAR)( 'MyClass', # class
442 'LEXICAL', # no typeglob
443 \$slr, # referent
444 'Omni', # attr name
445 '-vorous' # eval'd attr data
446 'CHECK', # compiler phase
447 );
448
449 # sub fn :Ugly(sister) :Omni('po',tent()) {...}
450
451 MyClass::UGLY:ATTR(CODE)( 'SomeOtherClass', # class
452 \*SomeOtherClass::fn, # typeglob
453 \&SomeOtherClass::fn, # referent
454 'Ugly', # attr name
455 'sister' # eval'd attr data
456 'CHECK', # compiler phase
457 );
458
459 MyClass::Omni:ATTR(CODE)( 'SomeOtherClass', # class
460 \*SomeOtherClass::fn, # typeglob
461 \&SomeOtherClass::fn, # referent
462 'Omni', # attr name
463 ['po','acle'] # eval'd attr data
464 'CHECK', # compiler phase
465 );
466
467 # my @arr :Good :Omni(s/cie/nt/);
468
469 MyClass::Good:ATTR(ARRAY)( 'SomeOtherClass', # class
470 'LEXICAL', # no typeglob
471 \@arr, # referent
472 'Good', # attr name
473 undef # no attr data
474 'CHECK', # compiler phase
475 );
476
477 MyClass::Omni:ATTR(ARRAY)( 'SomeOtherClass', # class
478 'LEXICAL', # no typeglob
479 \@arr, # referent
480 'Omni', # attr name
481 "" # eval'd attr data
482 'CHECK', # compiler phase
483 );
484
485 # my %hsh :Good(q/bye) :Omni(q/bus/);
486
487 MyClass::Good:ATTR(HASH)( 'SomeOtherClass', # class
488 'LEXICAL', # no typeglob
489 \%hsh, # referent
490 'Good', # attr name
491 'q/bye' # raw attr data
492 'CHECK', # compiler phase
493 );
494
495 MyClass::Omni:ATTR(HASH)( 'SomeOtherClass', # class
496 'LEXICAL', # no typeglob
497 \%hsh, # referent
498 'Omni', # attr name
499 'bus' # eval'd attr data
500 'CHECK', # compiler phase
501 );
502
503 Installing handlers into UNIVERSAL, makes them...err..universal. For
504 example:
505
506 package Descriptions;
507 use Attribute::Handlers;
508
509 my %name;
510 sub name { return $name{$_[2]}⎪⎪*{$_[1]}{NAME} }
511
512 sub UNIVERSAL::Name :ATTR {
513 $name{$_[2]} = $_[4];
514 }
515
516 sub UNIVERSAL::Purpose :ATTR {
517 print STDERR "Purpose of ", &name, " is $_[4]\n";
518 }
519
520 sub UNIVERSAL::Unit :ATTR {
521 print STDERR &name, " measured in $_[4]\n";
522 }
523
524 Let's you write:
525
526 use Descriptions;
527
528 my $capacity : Name(capacity)
529 : Purpose(to store max storage capacity for files)
530 : Unit(Gb);
531
532 package Other;
533
534 sub foo : Purpose(to foo all data before barring it) { }
535
536 # etc.
537
539 "Bad attribute type: ATTR(%s)"
540 An attribute handler was specified with an ":ATTR(ref_type)", but
541 the type of referent it was defined to handle wasn't one of the
542 five permitted: "SCALAR", "ARRAY", "HASH", "CODE", or "ANY".
543
544 "Attribute handler %s doesn't handle %s attributes"
545 A handler for attributes of the specified name was defined, but not
546 for the specified type of declaration. Typically encountered whe
547 trying to apply a "VAR" attribute handler to a subroutine, or a
548 "SCALAR" attribute handler to some other type of variable.
549
550 "Declaration of %s attribute in package %s may clash with future
551 reserved word"
552 A handler for an attributes with an all-lowercase name was
553 declared. An attribute with an all-lowercase name might have a
554 meaning to Perl itself some day, even though most don't yet. Use a
555 mixed-case attribute name, instead.
556
557 "Can't have two ATTR specifiers on one subroutine"
558 You just can't, okay? Instead, put all the specifications together
559 with commas between them in a single "ATTR(specification)".
560
561 "Can't autotie a %s"
562 You can only declare autoties for types "SCALAR", "ARRAY", and
563 "HASH". They're the only things (apart from typeglobs -- which are
564 not declarable) that Perl can tie.
565
566 "Internal error: %s symbol went missing"
567 Something is rotten in the state of the program. An attributed sub‐
568 routine ceased to exist between the point it was declared and the
569 point at which its attribute handler(s) would have been called.
570
571 "Won't be able to apply END handler"
572 You have defined an END handler for an attribute that is being
573 applied to a lexical variable. Since the variable may not be
574 available during END this won't happen.
575
577 Damian Conway (damian@conway.org)
578
580 There are undoubtedly serious bugs lurking somewhere in code this funky
581 :-) Bug reports and other feedback are most welcome.
582
584 Copyright (c) 2001, Damian Conway. All Rights Reserved.
585 This module is free software. It may be used, redistributed
586 and/or modified under the same terms as Perl itself.
587
588
589
590perl v5.8.8 2001-09-21 Attribute::Handlers(3pm)