File Coverage

blib/lib/Attribute/Lexical.pm
Criterion Covered Total %
statement 133 161 82.6
branch 51 68 75.0
condition 12 26 46.1
subroutine 21 23 91.3
pod 3 3 100.0
total 220 281 78.2


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Attribute::Lexical - sane scoping of function/variable attributes
4              
5             =head1 SYNOPSIS
6              
7             use Attribute::Lexical "CODE:Funky" => \&funky_attr_handler;
8             sub thingy :Funky { ... }
9              
10             $handler = Attribute::Lexical->handler_for_caller([caller(0)],
11             "CODE:Funky");
12              
13             =head1 DESCRIPTION
14              
15             This module manages attributes that can be attached to subroutine and
16             variable declarations. Although it can be used directly, it is mainly
17             intended to be infrastructure for modules that supply particular attribute
18             semantics.
19              
20             Meanings are assigned to attributes by code which is usually supplied
21             by modules and which runs at compile time. The built-in mechanism for
22             attribute control is awkward to use, difficult in particular to enable
23             multiple attributes supplied by different modules, and it scopes attribute
24             meanings according to the package of the object to which attributes are
25             being applied. This module is intended to overcome these limitations.
26              
27             This module supplies a simple pragma to declare an attribute, associating
28             the attribute's name with a handler function that implements its
29             semantics. The declaration is lexically scoped, lasting only until the
30             end of the enclosing block. A declaration can be overridden, giving
31             an attribute name a different meaning or making it meaningless, in an
32             inner nested block.
33              
34             =head2 Applying attributes
35              
36             Attributes can be applied to variables or functions, where they are
37             declared. A variable (which must be named) can have attributes added
38             as part of a declaration with the C, C, or C keywords.
39             Variables may be of scalar, array, or hash type. A function can have
40             attributes added wherever the C keyword is used: on a declaration
41             of a named function, whether or not it defines the function body, or on
42             an anonymous function.
43              
44             An attribute list is introduced by a "B<:>" character, and attributes
45             are separated by "B<:>" or whitespace. Each attribute starts with
46             an identifier, and may also have a parenthesised string argument.
47             See L for details.
48              
49             Attributes for functions and C variables are applied at compile time.
50             For anonymous functions that close over external lexical variables, the
51             thing that has attributes applied is actually the prototype function,
52             which stores the code but is not associated with any set of variables and
53             so cannot be called. When a closure is created at runtime, it copies
54             the state of this prototype, and does not get any attribute handling.
55             Attributes for C and C variables, on the other hand, are
56             applied at runtime, when execution reaches the variable declaration.
57              
58             =head2 Attribute names
59              
60             As noted in the previous section, each type of attribute that can be
61             applied to an object is identified by a name, in standard identifier
62             syntax. The same identifier can also have different meanings depending
63             on the type of the object. So for the purposes of this module, an
64             attribute is identified by the combination of object type and attribute
65             identifier. These two parts are combined into one string, consisting
66             of type keyword ("B", "B", "B", or "B"),
67             "B<:>", and identifier. For example, the name "B" refers
68             to an attribute that can be applied to a function by syntax such as
69             "C".
70              
71             Attribute identifiers that consist entirely of lowercase letters may have
72             meanings built into Perl. Some are already defined, and others may be
73             defined in future versions. User-defined attributes should therefore
74             always have identifiers containing some other kind of character.
75             Most commonly they start with an uppercase letter.
76              
77             =head2 Handler functions
78              
79             Each declared attribute is implemented by a handler function, which is
80             a normal Perl function, and may be either named or anonymous. A single
81             function may handle many attributes. When a declared attribute is to be
82             applied to an object, the handler function is called with four arguments:
83              
84             =over
85              
86             =item *
87              
88             A reference to the target object. The handler function is expected to
89             do something to this object.
90              
91             =item *
92              
93             The identifier part of the name under which the attribute was invoked.
94             Normally not of interest, but possibly useful when reporting errors,
95             in case the handler was attached to a different name from usual.
96              
97             =item *
98              
99             The attribute argument string. This is what appears between parentheses
100             immediately following the attribute identifier. C if there was
101             no argument. A handler that is not expecting an argument should check
102             that no argument was supplied.
103              
104             =item *
105              
106             A reference to the array returned by the L
107             function that describes the site where the attribute was invoked.
108             This is mainly useful to implement lexical semantics, such as using the
109             prevailing package in the interpretation of the argument.
110              
111             =back
112              
113             Attribute handler functions are mainly called during compile time, but
114             those for C and C variables are routinely called at runtime.
115             Any handler can also be called as part of a string L,
116             when it is compile time for the code in the string but runtime for the
117             surrounding code.
118              
119             When a code attribute handler is called, the target function will not
120             necessarily have its body defined yet. Firstly, a function can be
121             pre-declared, so that it has a name and attributes but no body, and in
122             that case it might never get a body. But also, in a normal function
123             definition with a body, the attributes are processed before the body
124             has been attached to the function (although after it has been compiled).
125             If an attribute handler needs to operate on the function's body, it must
126             take special measures to cause code to run later.
127              
128             =cut
129              
130             package Attribute::Lexical;
131              
132 6     6   139443 { use 5.006001; }
  6         27  
133 6     6   2248 use Lexical::SealRequireHints 0.008;
  6         5789  
  6         39  
134 6     6   215 use warnings;
  6         15  
  6         222  
135 6     6   48 use strict;
  6         19  
  6         377  
136              
137 6     6   46 use constant _KLUDGE_HINT_LOCALIZE_HH => "$]" < 5.009004;
  6         16  
  6         609  
138 6     6   45 use constant _KLUDGE_RUNTIME_HINTS => "$]" < 5.009004;
  6         16  
  6         414  
139 6     6   49 use constant _KLUDGE_FAKE_MRO => "$]" < 5.009005;
  6         15  
  6         347  
140 6     6   46 use constant _KLUDGE_UNIVERSAL_INVOCANT => 1; # bug#68654 or bug#81098
  6         17  
  6         355  
141              
142 6     6   46 use Carp qw(croak);
  6         16  
  6         484  
143 6     6   2595 use Params::Classify 0.000 qw(is_string is_ref);
  6         17524  
  6         558  
144 6     6   4441 use if !_KLUDGE_FAKE_MRO, "mro";
  6         93  
  6         39  
145              
146             our $VERSION = "0.005";
147              
148             # Hints stored in %^H only maintain referenceful structure during the
149             # compilation phase. Copies of %^H that are accessible via caller(),
150             # which we need in order to support runtime use of the lexical state,
151             # flatten all values to plain strings. So %interned_handler permanently
152             # holds references to all handler functions seen, keyed by the string
153             # form of the reference.
154             my %interned_handler;
155              
156             {
157             package Attribute::Lexical::UNIVERSAL;
158             our $VERSION = "0.005";
159             }
160              
161             unshift @UNIVERSAL::ISA, "Attribute::Lexical::UNIVERSAL";
162              
163 2 50 33 2   163 foreach my $type (qw(SCALAR ARRAY HASH CODE)) { eval "
  2 100 33 46   7  
  2 50 33 2   6  
  2 50 66 9   7  
  4 0 33     39  
  4 50 33     32  
  0 100 33     0  
  0 100 66     0  
  4 100       25  
  2 100       4  
  2 50       6  
  2 100       7  
  2 50       20  
  2 50       79  
  2 0       16  
  0 50       0  
  2 100       126  
  0 100       0  
  0 100       0  
  0 50       0  
  0         0  
  0         0  
  0         0  
  46         47630  
  46         104  
  46         103  
  46         108  
  92         873  
  92         555  
  0         0  
  0         0  
  92         284  
  46         85  
  46         96  
  46         130  
  53         520  
  53         1575  
  37         171  
  16         78  
  46         1096  
  14         84  
  14         38  
  14         96  
  14         577  
  5         29  
  9         48  
  2         204  
  2         8  
  2         7  
  2         7  
  4         38  
  4         36  
  0         0  
  0         0  
  4         17  
  2         5  
  2         7  
  2         7  
  2         19  
  2         77  
  2         14  
  0         0  
  2         80  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  9         1402  
  9         23  
  9         20  
  9         23  
  18         143  
  18         250  
  0         0  
  0         0  
  18         60  
  9         18  
  9         20  
  9         28  
  9         60  
  9         287  
  7         34  
  2         11  
  9         268  
  2         5  
  2         7  
  2         11  
  2         81  
  0         0  
  2         16  
164             package Attribute::Lexical::UNIVERSAL;
165             my \$type = \"$type\";
166             sub MODIFY_${type}_ATTRIBUTES
167             {".q{
168             my $invocant = shift(@_);
169             my $target = shift(@_);
170             my @unhandled;
171             my @caller;
172             for(my $i = 0; ; $i++) {
173             @caller = caller($i);
174             if(!@caller || $caller[3] =~ /::BEGIN\z/) {
175             # Strangely not called via attributes::import.
176             # No idea of the relevant lexical environment,
177             # so don't handle any attributes.
178             ALL_UNHANDLED:
179             @unhandled = @_;
180             goto HANDLE_UNHANDLED;
181             }
182             if($caller[3] eq "attributes::import") {
183             if(Attribute::Lexical::_KLUDGE_RUNTIME_HINTS) {
184             # On earlier perls we can only get lexical
185             # hints during compilation, because %^H
186             # isn't shown by caller(). In that case,
187             # we check here that the attributes are
188             # being applied as part of compilation,
189             # indicated by attributes::import being
190             # called directly from a BEGIN block.
191             # If it's called elsewhere, including
192             # indirectly from within a BEGIN
193             # block, then it's a runtime attribute
194             # application, which we can't handle.
195             my @nextcall = caller($i+1);
196             unless(@nextcall &&
197             $nextcall[3] =~ /::BEGIN\z/) {
198             goto ALL_UNHANDLED;
199             }
200             }
201             last;
202             }
203             }
204             foreach my $attr (@_) {
205             my($ident, $arg) = ($attr =~ /\A
206             ([A-Za-z_][0-9A-Za-z_]*)
207             (?:\((.*)\))?
208             \z/sx);
209             if(defined($ident) && defined(my $handler = (
210             Attribute::Lexical::_KLUDGE_RUNTIME_HINTS ?
211             # %^H is not available through caller() on
212             # earlier perls. In that case, if called
213             # during compilation, we can kludge by
214             # looking at the current compilation %^H.
215             Attribute::Lexical->handler_for_compilation(
216             "$type:$ident")
217             :
218             Attribute::Lexical->handler_for_caller(
219             \@caller, "$type:$ident")
220             ))) {
221             $handler->($target, $ident, $arg, \@caller);
222             } else {
223             push @unhandled, $attr;
224             }
225             }
226             HANDLE_UNHANDLED:
227             return () unless @unhandled;
228             my $next;
229             if(Attribute::Lexical::_KLUDGE_FAKE_MRO) {
230             # next::can is not available in earlier perls, or at least
231             # not in the core, so do it manually.
232             my $found_self;
233             foreach my $class (@UNIVERSAL::ISA) {
234             if(!$found_self) {
235             $found_self = $class eq __PACKAGE__;
236             next;
237             }
238             $next = $class->can("MODIFY_${type}_ATTRIBUTES")
239             and last;
240             }
241             } else {
242             # On earlier perls next::can doesn't look at methods
243             # defined in UNIVERSAL and its superclases, where they
244             # are implicit ancestors. The first attempt at fixing
245             # that was just as broken, jumping backward in the class
246             # precedence list when dealing with universal superclasses
247             # and a real invocant. In either case, starting the
248             # search at the UNIVERSAL class produces sane results.
249             $next = (Attribute::Lexical::_KLUDGE_UNIVERSAL_INVOCANT ?
250             "UNIVERSAL" : $invocant)->next::can;
251             }
252             if($next) {
253             return $invocant->$next($target, @unhandled);
254             } else {
255             return @unhandled;
256             }
257             }."}
258             1;
259             " or die $@; }
260              
261             sub _check_attribute_name($) {
262 150 100   150   1115 croak "attribute name must be a string" unless is_string($_[0]);
263 144 100       4166 croak "malformed attribute name" unless $_[0] =~ qr/\A
264             (?:SCALAR|ARRAY|HASH|CODE):
265             [A-Za-z_][0-9A-Za-z_]*
266             \z/x;
267             }
268              
269             =head1 PACKAGE METHODS
270              
271             All these methods are meant to be invoked on the C
272             package.
273              
274             =over
275              
276             =item Attribute::Lexical->handler_for_caller(CALLER, NAME)
277              
278             Looks up the attribute named I (e.g., "B")
279             according to the lexical declarations prevailing in a specified place.
280             I must be a reference to an array of the form returned by
281             the L function, describing the lexical site
282             of interest. If the requested attribute is declared in scope then
283             a reference to the handler function is returned, otherwise C
284             is returned.
285              
286             This method is not available prior to Perl 5.9.4, because earlier Perls
287             don't make lexical state available at runtime.
288              
289             =cut
290              
291 6 50 100 6 1 2209 BEGIN { unless(_KLUDGE_RUNTIME_HINTS) { eval q{ sub handler_for_caller {
  6 100   66   875  
  66         325  
  66         259  
  66         418  
  66         1792  
292             my($class, $caller, $name) = @_;
293             _check_attribute_name($name);
294             my $h = ($caller->[10] || {})->{"Attribute::Lexical/$name"};
295             return defined($h) ? $interned_handler{$h} : undef;
296             } 1; } or die $@; } }
297              
298             =item Attribute::Lexical->handler(NAME)
299              
300             Looks up the attribute named I (e.g., "B") according
301             to the lexical declarations prevailing at the site of the call to this
302             method. If the requested attribute is declared in scope then a reference
303             to the handler function is returned, otherwise C is returned.
304              
305             This method is not available prior to Perl 5.9.4, because earlier Perls
306             don't make lexical state available at runtime.
307              
308             =cut
309              
310 6 50   6 1 28 BEGIN { unless(_KLUDGE_RUNTIME_HINTS) { eval q{
  6     0   858  
  0         0  
311             sub handler { shift->handler_for_caller([caller(0)], @_) }
312             1; } or die $@; } }
313              
314             =item Attribute::Lexical->handler_for_compilation(NAME)
315              
316             Looks up the attribute named I (e.g., "B") according to
317             the lexical declarations prevailing in the code currently being compiled.
318             If the requested attribute is declared in scope then a reference to the
319             handler function is returned, otherwise C is returned.
320              
321             =cut
322              
323             sub handler_for_compilation {
324 0     0 1 0 my($class, $name) = @_;
325 0         0 _check_attribute_name($name);
326 0         0 my $h = $^H{"Attribute::Lexical/$name"};
327 0 0       0 return defined($h) ? $interned_handler{$h} : undef;
328             }
329              
330             =item Attribute::Lexical->import(NAME => HANDLER, ...)
331              
332             Sets up lexical attribute declarations, in the lexical environment that
333             is currently compiling. Each I must be an attribute name (e.g.,
334             "B"), and each I must be a reference to a function.
335             The name is lexically associated with the handler function I.
336             Within the resulting scope, use of the attribute name will result in
337             the handler function being called to apply the attribute.
338              
339             =cut
340              
341             sub import {
342 69     69   83514 my $class = shift(@_);
343 69 100       736 croak "$class does no default importation" if @_ == 0;
344 68 100       328 croak "import list for $class must alternate name and handler"
345             unless @_ % 2 == 0;
346 67         102 $^H |= 0x20000 if _KLUDGE_HINT_LOCALIZE_HH; # implicit in later perls
347 67         253 for(my $i = 0; $i != @_; $i += 2) {
348 68         226 my($name, $handler) = @_[$i, $i+1];
349 68         244 _check_attribute_name($name);
350 57 100       341 croak "attribute handler must be a subroutine"
351             unless is_ref($handler, "CODE");
352 56         174 $interned_handler{"$handler"} = $handler;
353 56         3090 $^H{"Attribute::Lexical/$name"} = "$handler";
354             }
355             }
356              
357             =item Attribute::Lexical->unimport(NAME [=> HANDLER], ...)
358              
359             Sets up negative lexical attribute declarations, in the lexical
360             environment that is currently compiling. Each I must be
361             an attribute name (e.g., "B"). If the name is given
362             on its own, it is lexically dissociated from any handler function.
363             Within the resulting scope, the attribute name will not be recognised.
364             If a I (which must be a function reference) is specified with
365             a name, the name will be dissociated if and only if it is currently
366             handled by that function.
367              
368             =cut
369              
370             sub unimport {
371 17     17   6879 my $class = shift(@_);
372 17 100       176 croak "$class does no default unimportation" if @_ == 0;
373 16         23 $^H |= 0x20000 if _KLUDGE_HINT_LOCALIZE_HH; # implicit in later perls
374 16         48 for(my $i = 0; $i != @_; ) {
375 16         50 my $name = $_[$i++];
376 16         43 _check_attribute_name($name);
377 8 100       34 my $handler = is_ref($_[$i], "CODE") ? $_[$i++] : undef;
378 8         20 my $key = "Attribute::Lexical/$name";
379 8 100       64 next unless exists $^H{$key};
380 6 100       10 if($handler) {
381 4 100       92 next unless $interned_handler{$^H{$key}} == $handler;
382             }
383 4         169 delete $^H{$key};
384             }
385             }
386              
387             =back
388              
389             =head1 BUGS
390              
391             This module uses relatively new and experimental features of Perl, and
392             is liable to expose problems in the interpreter. On older versions of
393             Perl some of the necessary infrastructure is missing, so the module uses
394             workarounds, with varying degrees of success. Specifically:
395              
396             Prior to Perl 5.9.4, the lexical state of attribute declarations is not
397             available at runtime. Most attributes are handled at compile time,
398             when the lexical state is available, so the module largely works.
399             But C/C variables have attributes applied at runtime,
400             which won't work. Usually the attributes will be simply unavailable
401             at runtime, as if they were never declared, but some rare situations
402             involving declaring attributes inside a C block can confuse the
403             module into applying the wrong attribute handler.
404              
405             Prior to Perl 5.9.3, the lexical state of attribute declarations does
406             not propagate into string eval.
407              
408             Prior to Perl 5.8, attributes don't work at all on C variables.
409             Only function attributes can be used effectively on such old versions.
410              
411             This module tries quite hard to play nicely with other modules that manage
412             attributes, in particular L. However, the underlying
413             protocol for attribute management is tricky, and convoluted arrangements
414             of attribute managers are liable to tread on each other's toes.
415              
416             The management of handler functions is likely to run into trouble where
417             threads are used. Code compiled before any threads are created should
418             be OK, as should anything contained entirely within a single thread,
419             but code shared between threads will probably have trouble due to Perl
420             not properly sharing data structures.
421              
422             =head1 SEE ALSO
423              
424             L,
425             L
426              
427             =head1 AUTHOR
428              
429             Andrew Main (Zefram)
430              
431             =head1 COPYRIGHT
432              
433             Copyright (C) 2009, 2010, 2011, 2017
434             Andrew Main (Zefram)
435              
436             =head1 LICENSE
437              
438             This module is free software; you can redistribute it and/or modify it
439             under the same terms as Perl itself.
440              
441             =cut
442              
443             1;