File Coverage

blib/lib/PPIx/Regexp/Token/Delimiter.pm
Criterion Covered Total %
statement 25 25 100.0
branch 4 4 100.0
condition n/a
subroutine 9 9 100.0
pod 3 3 100.0
total 41 41 100.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             PPIx::Regexp::Token::Delimiter - Represent the delimiters of the regular expression
4              
5             =head1 SYNOPSIS
6              
7             use PPIx::Regexp::Dumper;
8             PPIx::Regexp::Dumper->new( 'qr{foo}smx' )
9             ->print();
10              
11             =head1 INHERITANCE
12              
13             C is a
14             L.
15              
16             C has no descendants.
17              
18             =head1 DESCRIPTION
19              
20             This token represents the delimiters of the regular expression. Since
21             the tokenizer has to figure out where these are anyway, this class is
22             used to give the lexer a hint about what is going on.
23              
24             =head1 METHODS
25              
26             This class provides no public methods beyond those provided by its
27             superclass.
28              
29             =cut
30              
31             package PPIx::Regexp::Token::Delimiter;
32              
33 9     9   63 use strict;
  9         18  
  9         275  
34 9     9   48 use warnings;
  9         18  
  9         240  
35              
36 9     9   43 use base qw{ PPIx::Regexp::Token::Structure };
  9         32  
  9         4464  
37              
38 9     9   74 use PPIx::Regexp::Constant qw{ MINIMUM_PERL @CARP_NOT };
  9         26  
  9         1745  
39              
40             our $VERSION = '0.087_01';
41              
42             # Return true if the token can be quantified, and false otherwise
43             # sub can_be_quantified { return };
44              
45             sub explain {
46 4     4 1 15 return 'Regular expression or replacement string delimiter';
47             }
48              
49             =head2 perl_version_introduced
50              
51             Experimentation with weird delimiters shows that they did not actually
52             work until Perl 5.8.3, so we return C<'5.008003'> for such delimiters.
53              
54             =cut
55              
56             sub perl_version_introduced {
57 124     124 1 1018 my ( $self ) = @_;
58 124 100       307 $self->content() =~ m/ \A [[:^ascii:]] \z /smx
59             and return '5.008003';
60 119         363 return MINIMUM_PERL;
61             }
62              
63             =head2 perl_version_removed
64              
65             Perl 5.29.0 made fatal the use of non-standalone graphemes as regular
66             expression delimiters. Because non-characters and permanently unassigned
67             code points are still allowed per F, I take this to
68             mean characters that match C (i.e. combining diacritical
69             marks). But this regular expression does not compile under Perl 5.6.
70              
71             So:
72              
73             This method returns C<'5.029'> for such delimiters B the
74             requisite regular expression compiles. Otherwise it return C.
75              
76             =cut
77              
78             # Perl 5.29.0 disallows unassigned code points and combining code points
79             # as delimiters. Unfortunately for me non-characters and illegal
80             # characters are explicitly allowed. Still more unfortunately, these
81             # match /\p{Unassigned}/. So before I match a deprecated characer, I
82             # have to assert that the character is neither a non-character
83             # (\p{Noncharacter_code_point}) nor an illegal Unicode character
84             # (\P{Any}).
85 9     9   830 use constant WEIRD_CHAR_RE => eval ## no critic (ProhibitStringyEval,RequireCheckingReturnValueOfEval)
  9         5798  
  9         405  
  9         197  
86             'qr<
87             (?! [\p{Noncharacter_code_point}\P{Any}] )
88             [\p{Unassigned}\p{Mark}]
89 9     9   88 >smx';
  9         19  
90              
91             sub perl_version_removed {
92 127     127 1 1522 my ( $self ) = @_;
93 127 100       311 WEIRD_CHAR_RE
94             and $self->content() =~ WEIRD_CHAR_RE
95             and return '5.029';
96             # I respectfully disagree with Perl Best Practices on the
97             # following. When this method is called in list context it MUST
98             # return undef if that's the right answer, NOT an empty list.
99             # Otherwise hash constructors have the wrong number of elements.
100 126         444 return undef; ## no critic (ProhibitExplicitReturnUndef)
101             }
102              
103             1;
104              
105             __END__