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   91024 use 5.010001;
  3         11  
  3         138  
4 3     3   17 use strict;
  3         4  
  3         189  
5 3     3   15 use warnings;
  3         6  
  3         96  
6 3     3   12 no warnings qw( void once uninitialized );
  3         12  
  3         316  
7              
8             BEGIN {
9 3     3   7 $PerlX::QuoteOperator::Inescapable::AUTHORITY = 'cpan:TOBYINK';
10 3         64 $PerlX::QuoteOperator::Inescapable::VERSION = '0.001';
11             }
12              
13 3     3   16 use Carp qw/croak/;
  3         12  
  3         234  
14 3     3   3717 use Devel::Declare;
  3         31612  
  3         21  
15 3     3   5045 use Data::OptList;
  3         50976  
  3         50  
16 3     3   121 use Sub::Install qw/install_sub/;
  3         3  
  3         12  
17              
18 3     3   288 use parent qw/Devel::Declare::Context::Simple/;
  3         4  
  3         27  
19              
20             sub import
21             {
22 3     3   40 my $caller = caller;
23 3         8 my $self = shift;
24            
25 3 100       23 @_ = 'Q' unless @_;
26 3         19 my $optlist = Data::OptList::mkopt(\@_);
27            
28 3         145 for my $opt ( @$optlist )
29             {
30 3         8 my ($declarator, $callback) = @$opt;
31 3   100 18   27 $callback //= sub ($) { +shift };
  18         94  
32 3 50       13 $callback = delete $callback->{'-with'} if ref $callback eq 'HASH';
33            
34 3 50       32 $self = $self->new unless ref $self;
35             Devel::Declare->setup_for(
36             $caller,
37 36     36   4068 { $declarator => { const => sub { $self->_parser(@_) } } }
38 3         69 );
39            
40 3         179 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   48 my $self = shift;
56 36         570 $self->init(@_);
57            
58 36         576 $self->skip_declarator;
59 36         800 $self->skipspace;
60            
61 36         314 my $linestr = $self->get_linestr;
62            
63 36         211 my $remaining = substr($linestr, $self->offset);
64 36         149 my $starter = substr($remaining, 0, 1);
65 36         77 my $ender = $self->_ender($starter);
66            
67 36         106 my $ending = index($remaining, $ender, 1);
68 36 100       630 croak "Unterminated inescapable quoted string found: '$remaining'" if $ending < 0;
69            
70 34         93 substr($remaining, 0, $ending+1) = sprintf("('%s')", $self->_quote(substr $remaining, 1, $ending-1));
71 34         110 substr($linestr, $self->offset) = $remaining;
72            
73 34         208 $self->set_linestr($linestr);
74             }
75              
76             sub _ender
77             {
78 36     36   50 my ($self, $str) = @_;
79             {
80 36   66     304 '(' => ')',
81             '{' => '}',
82             '[' => ']',
83             '<' => '>',
84             }->{$str} // $str;
85             }
86              
87             sub _quote
88             {
89 34     34   72 my ($self, $str) = @_;
90 34         205 $str =~ s{([\\\'])}{\\$1}g;
91 34         181 return $str;
92             }
93              
94             __FILE__
95             __END__