File Coverage

blib/lib/BEGIN/Lift.pm
Criterion Covered Total %
statement 40 40 100.0
branch 4 4 100.0
condition n/a
subroutine 12 12 100.0
pod 1 1 100.0
total 57 57 100.0


line stmt bran cond sub pod time code
1             package BEGIN::Lift;
2             # ABSTRACT: Lift subroutine calls into the BEGIN phase
3              
4 9     9   515958 use strict;
  9         101  
  9         262  
5 9     9   49 use warnings;
  9         18  
  9         422  
6              
7             our $VERSION;
8             our $AUTHORITY;
9              
10 9     9   3123 use Sub::Name ();
  9         4300  
  9         297  
11 9     9   2391 use Devel::Hook ();
  9         7119  
  9         253  
12              
13 9     9   2909 use Devel::CallParser;
  9         19929  
  9         523  
14 9     9   73 use XSLoader;
  9         22  
  9         616  
15             BEGIN {
16 9     9   33 $VERSION = '0.07';
17 9         20 $AUTHORITY = 'cpan:STEVAN';
18 9         3584 XSLoader::load( __PACKAGE__, $VERSION );
19             }
20              
21             sub install {
22 8     8 1 4735 my ($pkg, $method, $handler) = @_;
23              
24             # need to force a new CV each time here
25             # not entirely sure why, but I assume
26             # that perl was trying to optimize things
27             # which is not what I actually want.
28 8         606 my $cv = eval 'sub {}';
29              
30             # now we need to install the stub
31             # we just created, but first we need to
32             # verify that we are the only ones using
33             # the typeglob we are installing into.
34             # This makes it easier/safer to delete
35             # the stub before runtime.
36             {
37 9     9   70 no strict 'refs';
  9         19  
  9         1695  
  8         25  
38             die "Cannot install the lifted keyword ($method) into package ($pkg) when that typeglob (\*${pkg}::${method}) already exists"
39 8 100       18 if exists ${"${pkg}::"}{$method};
  8         70  
40 7         14 *{"${pkg}::${method}"} = $cv;
  7         41  
41             }
42              
43             # give the handler a name so that
44             # it shows up sensibly in stack
45             # traces and the like ...
46 7         70 Sub::Name::subname( "${pkg}::${method}", $handler );
47              
48             # install the keyword handler ...
49             BEGIN::Lift::Util::install_keyword_handler(
50 10 100   10   4144 $cv, sub { $handler->( $_[0] ? $_[0]->() : () ) }
51 7         46 );
52              
53             # clean things up ...
54             Devel::Hook->unshift_UNITCHECK_hook(sub {
55 9     9   64 no strict 'refs';
  9         18  
  9         809  
56             # NOTE:
57             # this is safe only because we
58             # confirmed above that there was
59             # no other use of this typeglob
60             # and so it is ok to delete
61 7     7   9897 delete ${"${pkg}::"}{$method}
  7         3773  
62 7         60 });
63             }
64              
65             1;
66              
67             __END__