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