Commit | Line | Data |
---|---|---|
0e9b9e0c | 1 | ============================================================================== |
b9243681 | 2 | Attribute::Handlers |
0e9b9e0c JH |
3 | ============================================================================== |
4 | ||
5 | ||
6 | NAME | |
7 | Attribute::Handlers - Simpler definition of attribute handlers | |
8 | ||
b9243681 S |
9 | VERSION |
10 | This document describes version 0.79 of Attribute::Handlers, released | |
11 | November 25, 2007. | |
12 | ||
13 | SYNOPSIS | |
14 | package MyClass; | |
12c541f4 | 15 | require 5.006; |
b9243681 S |
16 | use Attribute::Handlers; |
17 | no warnings 'redefine'; | |
18 | ||
19 | ||
20 | sub Good : ATTR(SCALAR) { | |
21 | my ($package, $symbol, $referent, $attr, $data) = @_; | |
22 | ||
23 | # Invoked for any scalar variable with a :Good attribute, | |
24 | # provided the variable was declared in MyClass (or | |
25 | # a derived class) or typed to MyClass. | |
26 | ||
27 | # Do whatever to $referent here (executed in CHECK phase). | |
28 | ... | |
29 | } | |
30 | ||
31 | sub Bad : ATTR(SCALAR) { | |
32 | # Invoked for any scalar variable with a :Bad attribute, | |
33 | # provided the variable was declared in MyClass (or | |
34 | # a derived class) or typed to MyClass. | |
35 | ... | |
36 | } | |
37 | ||
38 | sub Good : ATTR(ARRAY) { | |
39 | # Invoked for any array variable with a :Good attribute, | |
40 | # provided the variable was declared in MyClass (or | |
41 | # a derived class) or typed to MyClass. | |
42 | ... | |
43 | } | |
44 | ||
45 | sub Good : ATTR(HASH) { | |
46 | # Invoked for any hash variable with a :Good attribute, | |
47 | # provided the variable was declared in MyClass (or | |
48 | # a derived class) or typed to MyClass. | |
49 | ... | |
50 | } | |
51 | ||
52 | sub Ugly : ATTR(CODE) { | |
53 | # Invoked for any subroutine declared in MyClass (or a | |
54 | # derived class) with an :Ugly attribute. | |
55 | ... | |
56 | } | |
57 | ||
58 | sub Omni : ATTR { | |
59 | # Invoked for any scalar, array, hash, or subroutine | |
60 | # with an :Omni attribute, provided the variable or | |
61 | # subroutine was declared in MyClass (or a derived class) | |
62 | # or the variable was typed to MyClass. | |
63 | # Use ref($_[2]) to determine what kind of referent it was. | |
64 | ... | |
65 | } | |
66 | ||
67 | ||
68 | use Attribute::Handlers autotie => { Cycle => Tie::Cycle }; | |
69 | ||
70 | my $next : Cycle(['A'..'Z']); | |
71 | ||
0e9b9e0c JH |
72 | DESCRIPTION |
73 | This module, when inherited by a package, allows that package's class to | |
74 | define attribute handler subroutines for specific attributes. Variables | |
75 | and subroutines subsequently defined in that package, or in packages | |
76 | derived from that package may be given attributes with the same names as | |
b9243681 S |
77 | the attribute handler subroutines, which will then be called in one of |
78 | the compilation phases (i.e. in a "BEGIN", "CHECK", "INIT", or "END" | |
79 | block). ("UNITCHECK" blocks don't correspond to a global compilation | |
80 | phase, so they can't be specified here.) | |
0e9b9e0c | 81 | |
b9243681 S |
82 | To create a handler, define it as a subroutine with the same name as the |
83 | desired attribute, and declare the subroutine itself with the attribute | |
84 | ":ATTR". For example: | |
0e9b9e0c | 85 | |
b9243681 S |
86 | package LoudDecl; |
87 | use Attribute::Handlers; | |
0e9b9e0c | 88 | |
b9243681 S |
89 | sub Loud :ATTR { |
90 | my ($package, $symbol, $referent, $attr, $data, $phase, $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 | } | |
0e9b9e0c | 100 | |
b9243681 S |
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: | |
0e9b9e0c | 104 | |
b9243681 | 105 | package LoudDecl; |
0e9b9e0c | 106 | |
b9243681 | 107 | sub foo: Loud {...} |
0e9b9e0c | 108 | |
b9243681 | 109 | causes the above handler to be invoked, and passed: |
0e9b9e0c | 110 | |
b9243681 | 111 | [0] the name of the package into which it was declared; |
0e9b9e0c | 112 | |
b9243681 S |
113 | [1] a reference to the symbol table entry (typeglob) containing the |
114 | subroutine; | |
0e9b9e0c | 115 | |
b9243681 | 116 | [2] a reference to the subroutine; |
0e9b9e0c | 117 | |
b9243681 | 118 | [3] the name of the attribute; |
0e9b9e0c | 119 | |
b9243681 | 120 | [4] any data associated with that attribute; |
0e9b9e0c | 121 | |
b9243681 | 122 | [5] the name of the phase in which the handler is being invoked; |
0e9b9e0c | 123 | |
b9243681 | 124 | [6] the filename in which the handler is being invoked; |
0e9b9e0c | 125 | |
b9243681 | 126 | [7] the line number in this file. |
0e9b9e0c | 127 | |
b9243681 S |
128 | Likewise, declaring any variables with the ":Loud" attribute within the |
129 | package: | |
0e9b9e0c | 130 | |
b9243681 | 131 | package LoudDecl; |
0e9b9e0c | 132 | |
b9243681 S |
133 | my $foo :Loud; |
134 | my @foo :Loud; | |
135 | my %foo :Loud; | |
0e9b9e0c | 136 | |
b9243681 S |
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). | |
0e9b9e0c | 139 | |
b9243681 S |
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 to | |
145 | 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 argument | |
158 | ($_[4]) to a useable form before passing it to the handler (but see | |
159 | "Non-interpretive attribute handlers"). If those efforts succeed, the | |
160 | interpreted data is passed in an array reference; if they fail, the raw | |
161 | 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/my, 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 as | |
178 | 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 variable | |
190 | is ascribed an attribute, the handler that is invoked is the one | |
191 | 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 also | |
201 | 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 useable 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 to | |
271 | 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 | Note that we now have to pass the cycling values as an array reference, | |
345 | since the "autotie" mechanism passes "tie" a list of arguments as a list | |
346 | (as in the Tie::Whatever example), *not* as an array reference (as in | |
347 | the original Tie::Cycle example at the start of this section). | |
348 | ||
349 | The argument after 'autotie' is a reference to a hash in which each key | |
350 | is the name of an attribute to be created, and each value is the class | |
351 | to which variables ascribed that attribute should be tied. | |
352 | ||
353 | Note that there is no longer any need to import the Tie::Cycle module -- | |
354 | Attribute::Handlers takes care of that automagically. You can even pass | |
355 | arguments to the module's "import" subroutine, by appending them to the | |
356 | class name. For example: | |
357 | ||
358 | use Attribute::Handlers | |
359 | autotie => { Dir => 'Tie::Dir qw(DIR_UNLINK)' }; | |
360 | ||
361 | If the attribute name is unqualified, the attribute is installed in the | |
362 | current package. Otherwise it is installed in the qualifier's package: | |
363 | ||
364 | package Here; | |
365 | ||
366 | use Attribute::Handlers autotie => { | |
367 | Other::Good => Tie::SecureHash, # tie attr installed in Other:: | |
368 | Bad => Tie::Taxes, # tie attr installed in Here:: | |
369 | UNIVERSAL::Ugly => Software::Patent # tie attr installed everywhere | |
370 | }; | |
371 | ||
372 | Autoties are most commonly used in the module to which they actually | |
373 | tie, and need to export their attributes to any module that calls them. | |
374 | To facilitate this, Attribute::Handlers recognizes a special | |
375 | "pseudo-class" -- "__CALLER__", which may be specified as the qualifier | |
376 | of an attribute: | |
377 | ||
378 | package Tie::Me::Kangaroo:Down::Sport; | |
379 | ||
380 | use Attribute::Handlers autotie => { '__CALLER__::Roo' => __PACKAGE__ }; | |
381 | ||
382 | This causes Attribute::Handlers to define the "Roo" attribute in the | |
383 | package that imports the Tie::Me::Kangaroo:Down::Sport module. | |
384 | ||
385 | Note that it is important to quote the __CALLER__::Roo identifier | |
386 | because a bug in perl 5.8 will refuse to parse it and cause an unknown | |
387 | error. | |
388 | ||
389 | Passing the tied object to "tie" | |
390 | Occasionally it is important to pass a reference to the object being | |
391 | tied to the TIESCALAR, TIEHASH, etc. that ties it. | |
392 | ||
393 | The "autotie" mechanism supports this too. The following code: | |
394 | ||
395 | use Attribute::Handlers autotieref => { Selfish => Tie::Selfish }; | |
396 | my $var : Selfish(@args); | |
397 | ||
398 | has the same effect as: | |
399 | ||
400 | tie my $var, 'Tie::Selfish', @args; | |
401 | ||
402 | But when "autotieref" is used instead of "autotie": | |
403 | ||
404 | use Attribute::Handlers autotieref => { Selfish => Tie::Selfish }; | |
405 | my $var : Selfish(@args); | |
406 | ||
407 | the effect is to pass the "tie" call an extra reference to the variable | |
408 | being tied: | |
409 | ||
410 | tie my $var, 'Tie::Selfish', \$var, @args; | |
411 | ||
412 | EXAMPLES | |
413 | If the class shown in SYNOPSIS were placed in the MyClass.pm module, | |
414 | then the following code: | |
415 | ||
416 | package main; | |
417 | use MyClass; | |
418 | ||
419 | my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous); | |
420 | ||
421 | package SomeOtherClass; | |
422 | use base MyClass; | |
423 | ||
424 | sub tent { 'acle' } | |
425 | ||
426 | sub fn :Ugly(sister) :Omni('po',tent()) {...} | |
427 | my @arr :Good :Omni(s/cie/nt/); | |
428 | my %hsh :Good(q/bye/) :Omni(q/bus/); | |
429 | ||
430 | would cause the following handlers to be invoked: | |
431 | ||
432 | # my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous); | |
433 | ||
434 | MyClass::Good:ATTR(SCALAR)( 'MyClass', # class | |
435 | 'LEXICAL', # no typeglob | |
436 | \$slr, # referent | |
437 | 'Good', # attr name | |
438 | undef # no attr data | |
439 | 'CHECK', # compiler phase | |
440 | ); | |
441 | ||
442 | MyClass::Bad:ATTR(SCALAR)( 'MyClass', # class | |
443 | 'LEXICAL', # no typeglob | |
444 | \$slr, # referent | |
445 | 'Bad', # attr name | |
446 | 0 # eval'd attr data | |
447 | 'CHECK', # compiler phase | |
448 | ); | |
449 | ||
450 | MyClass::Omni:ATTR(SCALAR)( 'MyClass', # class | |
451 | 'LEXICAL', # no typeglob | |
452 | \$slr, # referent | |
453 | 'Omni', # attr name | |
454 | '-vorous' # eval'd attr data | |
455 | 'CHECK', # compiler phase | |
456 | ); | |
457 | ||
458 | ||
459 | # sub fn :Ugly(sister) :Omni('po',tent()) {...} | |
460 | ||
461 | MyClass::UGLY:ATTR(CODE)( 'SomeOtherClass', # class | |
462 | \*SomeOtherClass::fn, # typeglob | |
463 | \&SomeOtherClass::fn, # referent | |
464 | 'Ugly', # attr name | |
465 | 'sister' # eval'd attr data | |
466 | 'CHECK', # compiler phase | |
467 | ); | |
468 | ||
469 | MyClass::Omni:ATTR(CODE)( 'SomeOtherClass', # class | |
470 | \*SomeOtherClass::fn, # typeglob | |
471 | \&SomeOtherClass::fn, # referent | |
472 | 'Omni', # attr name | |
473 | ['po','acle'] # eval'd attr data | |
474 | 'CHECK', # compiler phase | |
475 | ); | |
476 | ||
477 | ||
478 | # my @arr :Good :Omni(s/cie/nt/); | |
479 | ||
480 | MyClass::Good:ATTR(ARRAY)( 'SomeOtherClass', # class | |
481 | 'LEXICAL', # no typeglob | |
482 | \@arr, # referent | |
483 | 'Good', # attr name | |
484 | undef # no attr data | |
485 | 'CHECK', # compiler phase | |
486 | ); | |
487 | ||
488 | MyClass::Omni:ATTR(ARRAY)( 'SomeOtherClass', # class | |
489 | 'LEXICAL', # no typeglob | |
490 | \@arr, # referent | |
491 | 'Omni', # attr name | |
492 | "" # eval'd attr data | |
493 | 'CHECK', # compiler phase | |
494 | ); | |
495 | ||
496 | ||
497 | # my %hsh :Good(q/bye) :Omni(q/bus/); | |
498 | ||
499 | MyClass::Good:ATTR(HASH)( 'SomeOtherClass', # class | |
500 | 'LEXICAL', # no typeglob | |
501 | \%hsh, # referent | |
502 | 'Good', # attr name | |
503 | 'q/bye' # raw attr data | |
504 | 'CHECK', # compiler phase | |
505 | ); | |
506 | ||
507 | MyClass::Omni:ATTR(HASH)( 'SomeOtherClass', # class | |
508 | 'LEXICAL', # no typeglob | |
509 | \%hsh, # referent | |
510 | 'Omni', # attr name | |
511 | 'bus' # eval'd attr data | |
512 | 'CHECK', # compiler phase | |
513 | ); | |
514 | ||
515 | Installing handlers into UNIVERSAL, makes them...err..universal. For | |
516 | example: | |
517 | ||
518 | package Descriptions; | |
519 | use Attribute::Handlers; | |
520 | ||
521 | my %name; | |
522 | sub name { return $name{$_[2]}||*{$_[1]}{NAME} } | |
523 | ||
524 | sub UNIVERSAL::Name :ATTR { | |
525 | $name{$_[2]} = $_[4]; | |
526 | } | |
527 | ||
528 | sub UNIVERSAL::Purpose :ATTR { | |
529 | print STDERR "Purpose of ", &name, " is $_[4]\n"; | |
530 | } | |
531 | ||
532 | sub UNIVERSAL::Unit :ATTR { | |
533 | print STDERR &name, " measured in $_[4]\n"; | |
534 | } | |
535 | ||
536 | Let's you write: | |
537 | ||
538 | use Descriptions; | |
539 | ||
540 | my $capacity : Name(capacity) | |
541 | : Purpose(to store max storage capacity for files) | |
542 | : Unit(Gb); | |
543 | ||
544 | ||
545 | package Other; | |
546 | ||
547 | sub foo : Purpose(to foo all data before barring it) { } | |
548 | ||
549 | # etc. | |
550 | ||
551 | DIAGNOSTICS | |
552 | "Bad attribute type: ATTR(%s)" | |
553 | An attribute handler was specified with an ":ATTR(*ref_type*)", but | |
554 | the type of referent it was defined to handle wasn't one of the five | |
555 | permitted: "SCALAR", "ARRAY", "HASH", "CODE", or "ANY". | |
556 | ||
557 | "Attribute handler %s doesn't handle %s attributes" | |
558 | A handler for attributes of the specified name *was* defined, but | |
559 | not for the specified type of declaration. Typically encountered whe | |
560 | trying to apply a "VAR" attribute handler to a subroutine, or a | |
561 | "SCALAR" attribute handler to some other type of variable. | |
562 | ||
563 | "Declaration of %s attribute in package %s may clash with future | |
564 | reserved word" | |
565 | A handler for an attributes with an all-lowercase name was declared. | |
566 | An attribute with an all-lowercase name might have a meaning to Perl | |
567 | itself some day, even though most don't yet. Use a mixed-case | |
568 | attribute name, instead. | |
569 | ||
570 | "Can't have two ATTR specifiers on one subroutine" | |
571 | You just can't, okay? Instead, put all the specifications together | |
572 | with commas between them in a single "ATTR(*specification*)". | |
573 | ||
574 | "Can't autotie a %s" | |
575 | You can only declare autoties for types "SCALAR", "ARRAY", and | |
576 | "HASH". They're the only things (apart from typeglobs -- which are | |
577 | not declarable) that Perl can tie. | |
578 | ||
579 | "Internal error: %s symbol went missing" | |
580 | Something is rotten in the state of the program. An attributed | |
581 | subroutine ceased to exist between the point it was declared and the | |
582 | point at which its attribute handler(s) would have been called. | |
583 | ||
584 | "Won't be able to apply END handler" | |
585 | You have defined an END handler for an attribute that is being | |
586 | applied to a lexical variable. Since the variable may not be | |
587 | available during END this won't happen. | |
588 | ||
589 | AUTHOR | |
590 | Damian Conway (damian@conway.org). The maintainer of this module is now | |
591 | Rafael Garcia-Suarez (rgarciasuarez@gmail.com). | |
592 | ||
593 | Maintainer of the CPAN release is Steffen Mueller (smueller@cpan.org). | |
594 | Contact him with technical difficulties with respect to the packaging of | |
595 | the CPAN module. | |
596 | ||
597 | BUGS | |
598 | There are undoubtedly serious bugs lurking somewhere in code this funky | |
599 | :-) Bug reports and other feedback are most welcome. | |
600 | ||
601 | COPYRIGHT AND LICENSE | |
602 | Copyright (c) 2001-2009, Damian Conway. All Rights Reserved. | |
603 | This module is free software. It may be used, redistributed | |
604 | and/or modified under the same terms as Perl itself. | |
0e9b9e0c | 605 |