File Coverage

blib/lib/PPIx/Regexp/Token/Reference.pm
Criterion Covered Total %
statement 65 66 98.4
branch 19 22 86.3
condition 3 6 50.0
subroutine 14 15 93.3
pod 6 6 100.0
total 107 115 93.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             PPIx::Regexp::Token::Reference - Represent a reference to a capture
4              
5             =head1 SYNOPSIS
6              
7             use PPIx::Regexp::Dumper;
8             PPIx::Regexp::Dumper->new( 'qr{\1}smx' )
9             ->print();
10              
11             =head1 INHERITANCE
12              
13             C is a
14             L.
15              
16             C is the parent of
17             L,
18             L and
19             L.
20              
21             =head1 DESCRIPTION
22              
23             This abstract class represents a reference to a capture buffer, either
24             numbered or named. It should never be instantiated, but it provides a
25             number of methods to its subclasses.
26              
27             =head1 METHODS
28              
29             This class provides the following public methods. Methods not documented
30             here are private, and unsupported in the sense that the author reserves
31             the right to change or remove them without notice.
32              
33             =cut
34              
35             package PPIx::Regexp::Token::Reference;
36              
37 9     9   85 use strict;
  9         18  
  9         264  
38 9     9   46 use warnings;
  9         22  
  9         233  
39              
40 9     9   44 use base qw{ PPIx::Regexp::Token };
  9         20  
  9         792  
41              
42 9     9   66 use Carp qw{ confess };
  9         21  
  9         538  
43 9     9   63 use List::Util qw{ first };
  9         30  
  9         708  
44 9     9   88 use PPIx::Regexp::Constant qw{ @CARP_NOT };
  9         31  
  9         7571  
45              
46             our $VERSION = '0.087';
47              
48             sub __new {
49 113     113   866 my ( $class, $content, %arg ) = @_;
50              
51 113 100       577 if ( defined $arg{capture} ) {
    100          
52             } elsif ( defined $arg{tokenizer} ) {
53 101     116   702 $arg{capture} = first { defined $_ } $arg{tokenizer}->capture();
  116         369  
54             }
55              
56 113 100       553 unless ( defined $arg{capture} ) {
57 24         103 foreach ( $class->__PPIX_TOKEN__recognize() ) {
58 49         77 my ( $re, $a ) = @{ $_ };
  49         105  
59 49 100       385 $content =~ $re or next;
60 24         50 @arg{ keys %{ $a } } = @{ $a }{ keys %{ $a } };
  24         62  
  24         41  
  24         82  
61 24         98 foreach my $inx ( 1 .. $#- ) {
62 34 100       138 defined $-[$inx] or next;
63 21         110 $arg{capture} = substr $content, $-[$inx], $+[$inx] - $-[$inx];
64 21         50 last;
65             }
66 24         44 last;
67             }
68             }
69              
70             defined $arg{capture}
71 113 50       425 or confess q{Programming error - reference '},
72             $content, q{' of unknown form};
73              
74 113 50       566 my $self = $class->SUPER::__new( $content, %arg )
75             or return;
76              
77 113         346 $self->{is_named} = $arg{is_named};
78              
79 113         304 my $capture = delete $arg{capture};
80              
81 113 100       534 if ( $self->{is_named} ) {
    100          
82 35         156 $self->{absolute} = undef;
83 35         100 $self->{is_relative} = undef;
84 35         103 $self->{name} = $capture;
85             } elsif ( $capture !~ m/ \A [-+] /smx ) {
86 59         282 $self->{absolute} = $self->{number} = $capture;
87 59         152 $self->{is_relative} = undef;
88             } else {
89 19         63 $self->{number} = $capture;
90 19         58 $self->{is_relative} = 1;
91             }
92              
93 113         411 return $self;
94             }
95              
96             =head2 absolute
97              
98             print "The absolute reference is ", $ref->absolute(), "\n";
99              
100             This method returns the absolute number of the capture buffer referred
101             to. This is the same as number() for unsigned numeric references. If the
102             reference is to a named buffer, C is returned.
103              
104             =cut
105              
106             sub absolute {
107 69     69 1 181 my ( $self ) = @_;
108 69         241 return $self->{absolute};
109             }
110              
111             =head2 is_named
112              
113             $ref->is_named and print "named reference\n";
114              
115             This method returns true if the reference is named rather than numbered.
116              
117             =cut
118              
119             sub is_named {
120 87     87 1 192 my ( $self ) = @_;
121 87         333 return $self->{is_named};
122             }
123              
124             =head2 is_relative
125              
126             $ref->is_relative()
127             and print "relative numbered reference\n";
128              
129             This method returns true if the reference is numbered and it is a
130             relative number (i.e. if it is signed).
131              
132             =cut
133              
134             sub is_relative {
135 5     5 1 14 my ( $self ) = @_;
136 5         30 return $self->{is_relative};
137             }
138              
139             =head2 is_matcher
140              
141             This method returns a true value because, although we do not actually
142             perform an analysis on the referred-to entity, we presume it matches
143             something.
144              
145             =cut
146              
147 0     0 1 0 sub is_matcher { return 1; }
148              
149             =head2 name
150              
151             print "The name is ", $ref->name(), "\n";
152              
153             This method returns the name of the capture buffer referred to. In the
154             case of a reference to a numbered capture (i.e. C returns
155             false), this method returns C.
156              
157             =cut
158              
159             sub name {
160 39     39 1 102 my ( $self ) = @_;
161 39         166 return $self->{name};
162             }
163              
164             =head2 number
165              
166             print "The number is ", $ref->number(), "\n";
167              
168             This method returns the number of the capture buffer referred to. In the
169             case of a reference to a named capture (i.e. C returns true),
170             this method returns C.
171              
172             =cut
173              
174             sub number {
175 22     22 1 73 my ( $self ) = @_;
176 22         75 return $self->{number};
177             }
178              
179             # Called by the lexer to record the capture number.
180             sub __PPIX_LEXER__record_capture_number {
181 63     63   194 my ( $self, $number ) = @_;
182 63 50 66     378 if ( ! exists $self->{absolute} && exists $self->{number}
      33        
183             && $self->{number} =~ m/ \A [-+] /smx ) {
184              
185 10         43 my $delta = $self->{number};
186 10 100       122 $delta > 0 and --$delta; # no -0 or +0.
187 10         39 $self->{absolute} = $number + $delta;
188              
189             }
190 63         159 return $number;
191             }
192              
193             1;
194              
195             __END__