File Coverage

blib/lib/PerlX/QuoteOperator/Inescapable.pm
Criterion Covered Total %
statement 60 61 98.3
branch 6 8 75.0
condition 4 5 80.0
subroutine 16 17 94.1
pod n/a
total 86 91 94.5


line stmt bran cond sub pod time code
1             package PerlX::QuoteOperator::Inescapable;
2              
3 3     3   76417 use 5.010001;
  3         12  
  3         144  
4 3     3   18 use strict;
  3         5  
  3         105  
5 3     3   13 use warnings;
  3         10  
  3         87  
6 3     3   14 no warnings qw( void once uninitialized );
  3         4  
  3         168  
7              
8             BEGIN {
9 3     3   6 $PerlX::QuoteOperator::Inescapable::AUTHORITY = 'cpan:TOBYINK';
10 3         59 $PerlX::QuoteOperator::Inescapable::VERSION = '0.002';
11             }
12              
13 3     3   16 use Carp qw/croak/;
  3         4  
  3         222  
14 3     3   3542 use Devel::Declare;
  3         22670  
  3         17  
15 3     3   2869 use Data::OptList;
  3         33457  
  3         23  
16 3     3   114 use Sub::Install qw/install_sub/;
  3         6  
  3         14  
17              
18 3     3   280 use parent qw/Devel::Declare::Context::Simple/;
  3         27  
  3         25  
19              
20             sub import
21             {
22 3     3   38 my $caller = caller;
23 3         7 my $self = shift;
24            
25 3 100       19 @_ = 'Q' unless @_;
26 3         16 my $optlist = Data::OptList::mkopt(\@_);
27            
28 3         141 for my $opt ( @$optlist )
29             {
30 3         8 my ($declarator, $callback) = @$opt;
31 3   100 18   23 $callback //= sub ($) { +shift };
  18         82  
32 3 50       16 $callback = delete $callback->{'-with'} if ref $callback eq 'HASH';
33            
34 3 50       34 $self = $self->new unless ref $self;
35             Devel::Declare->setup_for(
36             $caller,
37 36     36   2964 { $declarator => { const => sub { $self->_parser(@_) } } }
38 3         72 );
39            
40 3         100 install_sub {
41             into => $caller,
42             as => $declarator,
43             code => $callback,
44             };
45             }
46             }
47              
48             sub unimport
49             {
50 0     0   0 $^H{(__PACKAGE__)} = undef;
51             }
52              
53             sub _parser
54             {
55 36     36   50 my $self = shift;
56 36         103 $self->init(@_);
57            
58 36         810 $self->skip_declarator;
59 36         885 $self->skipspace;
60            
61 36         273 my $linestr = $self->get_linestr;
62            
63 36         205 my $remaining = substr($linestr, $self->offset);
64 36         172 my $starter = substr($remaining, 0, 1);
65 36         73 my $ender = $self->_ender($starter);
66            
67 36         99 my $ending = index($remaining, $ender, 1);
68 36 100       607 croak "Unterminated inescapable quoted string found: '$remaining'" if $ending < 0;
69            
70 34         92 substr($remaining, 0, $ending+1) = sprintf("('%s')", $self->_quote(substr $remaining, 1, $ending-1));
71 34         131 substr($linestr, $self->offset) = $remaining;
72            
73 34         176 $self->set_linestr($linestr);
74             }
75              
76             sub _ender
77             {
78 36     36   51 my ($self, $str) = @_;
79             {
80 36   66     298 '(' => ')',
81             '{' => '}',
82             '[' => ']',
83             '<' => '>',
84             }->{$str} // $str;
85             }
86              
87             sub _quote
88             {
89 34     34   65 my ($self, $str) = @_;
90 34         194 $str =~ s{([\\\'])}{\\$1}g;
91 34         179 return $str;
92             }
93              
94             __FILE__
95             __END__