File Coverage

blib/lib/Regexp/DeferredExecution.pm
Criterion Covered Total %
statement 18 25 72.0
branch 1 4 25.0
condition n/a
subroutine 7 7 100.0
pod 0 1 0.0
total 26 37 70.2


line stmt bran cond sub pod time code
1             package Regexp::DeferredExecution;
2              
3 1     1   25874 use strict;
  1         2  
  1         40  
4 1     1   5 use vars qw($VERSION);
  1         2  
  1         73  
5              
6             $VERSION = '0.05';
7              
8 1         128 use Text::Balanced qw( extract_multiple
9             extract_codeblock
10 1     1   1131 );
  1         24007  
11              
12 1     1   9 use overload;
  1         2  
  1         4  
13              
14             sub import {
15 4     4   998 shift;
16 4         46 overload::constant('qr' => \&convert);
17             }
18              
19             sub unimport {
20 2     2   188 shift;
21 2         6 overload::remove_constant('qr');
22             }
23              
24             sub convert {
25              
26 10     10 0 164 my $re = shift;
27              
28 10 50       2406 return $re unless $re =~ m/\(\?\{/; # no need to alter this one.
29              
30 0           my @chunks =
31             extract_multiple($re,
32             [ qr/\(\? # '(?' (escaped)
33             (?=\{) # followed by '{' (lookahead)
34             /x,
35             \&extract_codeblock
36             ]
37             );
38              
39 0           for (my $i = 1 ; $i < @chunks ; $i++) {
40             # wrap all code into a closure and push onto the stack:
41 0 0         if ($chunks[$i-1] eq "(?") {
42 0           $chunks[$i] =~ s/\A \{
43             (.*)
44             \} \Z
45             /{
46             local \@Regexp::DeferredExecution::c = \@Regexp::DeferredExecution::c;
47             push \@Regexp::DeferredExecution::c, [\$^N, q{$1}];
48             }/msx;
49             }
50             }
51              
52 0           $re = join("", @chunks);
53              
54             # install the stack storage and execution code:
55 0           $re = "(?{
56             local \@Regexp::DeferredExecution::c = ();
57             })$re(?{
58             for (\@Regexp::DeferredExecution::c) {
59             \$^N = \$\$_[0];
60             eval \$\$_[1];
61             }
62             })";
63              
64 0           return $re;
65             }
66              
67             1;
68             __END__