File Coverage

blib/lib/Devel/Declare/Lexer/Token/String/Interpolator.pm
Criterion Covered Total %
statement 76 76 100.0
branch 39 54 72.2
condition 17 21 80.9
subroutine 5 5 100.0
pod 0 2 0.0
total 137 158 86.7


line stmt bran cond sub pod time code
1             package Devel::Declare::Lexer::Token::String::Interpolator;
2              
3 10     10   66 use strict;
  10         19  
  10         486  
4 10     10   61 use warnings;
  10         19  
  10         445  
5              
6 10     10   55 use Data::Dumper;
  10         26  
  10         13423  
7              
8             my $DEBUG = $Devel::Declare::Lexer::DEBUG;
9              
10             sub interpolate {
11 5     5 0 10 my ($string, @values) = @_;
12              
13 5         10 my $vars = deinterpolate($string);
14 5         11 my @varlist = (@$vars);
15 5 50       13 $DEBUG and print STDERR Dumper(@varlist) . "\n";
16 5         7 my $i = 0;
17 5 50       8 $DEBUG and print STDERR "old string: $string\n";
18 5         9 my $offset = 0;
19 5         5 for my $var (@varlist) {
20 9 50       19 $DEBUG and print STDERR "offset: $offset\n";
21 9         30 substr( $string, $var->{start} + $offset, $var->{length} ) = $values[$i];
22 9         10 my $oldlen = $var->{length};
23 9         10 my $newlen = length $values[$i];
24 9         15 $offset += ($newlen - $oldlen);
25 9 50       17 $DEBUG and print STDERR "new offset: $offset\n";
26 9         16 $i++;
27             }
28 5 50       11 $DEBUG and print STDERR "new string: $string\n";
29 5         33 return $string;
30             }
31              
32             sub deinterpolate {
33 30     30 0 43 my ($string) = @_;
34              
35 30         43 my @vars = ();
36              
37 30 50       69 $DEBUG and print STDERR "Deinterpolating '$string'\n";
38              
39 30         341 my @chars = split //, $string;
40              
41 30         78 my @procd = ();
42 30         37 my $tok = '';
43 30         38 my $pos = -1;
44 30         51 for my $char (@chars) {
45 999         1606 push @procd, $char;
46 999         1068 $pos++;
47 999 50       1792 $DEBUG and print STDERR "Got char '$char' at pos $pos\n";
48              
49 999 100 100     3269 if($char =~ /[^\w_{}\[\]:@\$]/ && $tok) {
50 33 50       68 $DEBUG and print STDERR "Captured token '$tok' at pos $pos (eot)\n";
51 33         157 push @vars, {
52             token => $tok,
53             start => $pos - (length $tok),
54             end => $pos,
55             length => (length $tok)
56             };
57 33         48 $tok = '';
58 33         53 next;
59             }
60             #if($tok && ($char !~ /[\$\@\%]/ || length $tok == 1)) {
61 966 100 100     3613 if($tok && ($char !~ /[\$\@]/ || length $tok == 1)) {
      66        
62 170 50       313 $DEBUG and print STDERR "Got tok '$tok' so far\n";
63 170         178 my $eot = 0;
64 170 100       1948 if($char =~ /[':]/) {
65             # do some forwardlooking
66 33         52 my $c = $chars[$pos + 1];
67             #if($c && $c =~ /[\s\$\%\@]/) {
68 33 100 66     163 if($c && $c =~ /[\s\$\@]/) { # hashes are only interpolated with $name{key} syntax
69 1         2 $eot = 1;
70             }
71             }
72 170 100       319 if(!$eot) {
73 169         193 $tok .= $char;
74 169         227 next;
75             }
76             }
77             #if($char =~ /[\$\@\%]/ || $tok) {
78 797 100 100     3545 if($char =~ /[\$\@]/ || $tok) {
79             #if($char =~ /[\$\@\%]/ && $tok && $tok !~ /^[\$\@\%]+$/) {
80 55 100 66     183 if( $tok && (($char =~ /[\$\@]/ && $tok !~ /^[\$\@]+$/))) {
      66        
81 8 50       20 $DEBUG and print STDERR "Captured token '$tok' at pos $pos\n";
82 8         40 push @vars, {
83             token => $tok,
84             start => $pos - (length $tok),
85             end => $pos,
86             length => (length $tok)
87             };
88 8         16 $tok = '';
89             }
90 55         62 my $capture = 0;
91 55 50       99 $DEBUG and print STDERR "Got tok '$tok' in varcap\n";
92 55 100       105 if(!$tok) {
93             # do some backtracking
94 54         64 my $ec = 0;
95 54         140 for(my $i = $pos - 1; $i >= 0; $i--) {
96 90         132 my $c = $procd[$i];
97 90 100       241 last if $c !~ /\\/;
98 37         35 $ec++;
99 37 50       105 $DEBUG and print STDERR "Got char '$c' at pos $i, ec $ec\n";
100             }
101 54 100       136 $capture = $ec % 2 == 0 ? 1 : 0;
102             #if($ec % 2 == 0) {
103             # print "probably a token\n";
104             #} else {
105             # print "probably not a token\n";
106             #}
107             }
108 55 50       100 $DEBUG and print STDERR "Got capture $capture\n\n";
109 55 100       108 $tok = $char if $capture;
110 55         88 next;
111             }
112             }
113              
114 30 100       76 if(wantarray) {
115 25 50       46 $DEBUG and print STDERR "Returning array of token names\n";
116 25         60 return map { $_->{token} } @vars;
  32         321  
117             }
118 5 50       10 $DEBUG and print STDERR "Returning arrayref\n";
119 5         32 return \@vars;
120             }
121              
122             1;