File Coverage

blib/lib/PerlX/Let.pm
Criterion Covered Total %
statement 41 41 100.0
branch 13 14 92.8
condition 5 6 83.3
subroutine 9 9 100.0
pod n/a
total 68 70 97.1


line stmt bran cond sub pod time code
1             package PerlX::Let;
2              
3             # ABSTRACT: Syntactic sugar for lexical state constants
4              
5 1     1   116202 use v5.12;
  1         11  
6              
7 1     1   5 use strict;
  1         2  
  1         28  
8 1     1   6 use warnings;
  1         2  
  1         24  
9              
10 1     1   404 use Const::Fast ();
  1         2158  
  1         23  
11 1     1   380 use Keyword::Simple 0.04;
  1         20898  
  1         32  
12 1     1   566 use Text::Balanced ();
  1         13678  
  1         358  
13              
14             our $VERSION = 'v0.2.7';
15              
16              
17             sub import {
18 1     1   12 Keyword::Simple::define 'let', \&_rewrite_let;
19             }
20              
21             sub unimport {
22 1     1   158 Keyword::Simple::undefine 'let';
23             }
24              
25             sub _rewrite_let {
26 11     11   15211 my ($ref) = @_;
27              
28 11         21 my $let = "";
29              
30 11         21 do {
31              
32 13         17 my ( $name, $val );
33              
34 13         35 ( $name, $$ref ) = Text::Balanced::extract_variable($$ref);
35 13 100       2064 die "A variable name is required for let" unless defined $name;
36 11 100       83 $$ref =~ s/^\s*\=>?\s*// or die "An assignment is required for let";
37 9         27 ( $val, $$ref ) = Text::Balanced::extract_quotelike($$ref);
38 9 100       393 ( $val, $$ref ) = Text::Balanced::extract_bracketed( $$ref, '({[' )
39             unless defined $val;
40              
41 9 100       745 unless ( defined $val ) {
42 6         18 ($val) = $$ref =~ /^(\S+)/;
43 6         25 $$ref =~ s/^\S+//;
44             }
45              
46 9 50       15 die "A value is required for let" unless defined $val;
47              
48 9 100 66     87 if ($val !~ /[\$\@\%\&]/ && ($] >= 5.028 || substr($name, 0, 1) eq '$')) {
      100        
49              
50             # We can't use Const::Fast on state variables, so we use
51             # this workaround.
52              
53 6         32 $let .= "use feature 'state'; state $name = $val; unless (state \$__perlx_let_state_is_set = 0) { Const::Fast::_make_readonly(\\$name); \$__perlx_let_state_is_set = 1; };";
54              
55             }
56             else {
57              
58 3         23 $let .= "Const::Fast::const my $name => $val; ";
59             }
60              
61             } while ( $$ref =~ s/^\s*,\s*// );
62              
63 7         9 my $code;
64              
65 7         16 ( $code, $$ref ) = Text::Balanced::extract_codeblock( $$ref, '{' );
66              
67 7 100       9742 if ($code) {
68 5         15 substr( $code, index( $code, '{' ) + 1, 0 ) = $let;
69 5         428 substr( $$ref, 0, 0 ) = $code;
70             }
71             else {
72 2         103 substr( $$ref, 0, 0 ) = $let;
73             }
74              
75             }
76              
77              
78              
79             1;
80              
81             __END__