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   59 use strict;
  9         11  
  9         280  
38 9     9   30 use warnings;
  9         11  
  9         327  
39              
40 9     9   31 use base qw{ PPIx::Regexp::Token };
  9         13  
  9         720  
41              
42 9     9   37 use Carp qw{ confess };
  9         11  
  9         470  
43 9     9   48 use List::Util qw{ first };
  9         10  
  9         445  
44 9     9   32 use PPIx::Regexp::Constant qw{ @CARP_NOT };
  9         12  
  9         6016  
45              
46             our $VERSION = '0.092';
47              
48             sub __new {
49 113     113   594 my ( $class, $content, %arg ) = @_;
50              
51 113 100       394 if ( defined $arg{capture} ) {
    100          
52             } elsif ( defined $arg{tokenizer} ) {
53 101     116   433 $arg{capture} = first { defined $_ } $arg{tokenizer}->capture();
  116         230  
54             }
55              
56 113 100       411 unless ( defined $arg{capture} ) {
57 24         77 foreach ( $class->__PPIX_TOKEN__recognize() ) {
58 49         59 my ( $re, $a ) = @{ $_ };
  49         104  
59 49 100       306 $content =~ $re or next;
60 24         33 @arg{ keys %{ $a } } = @{ $a }{ keys %{ $a } };
  24         47  
  24         31  
  24         51  
61 24         114 foreach my $inx ( 1 .. $#- ) {
62 34 100       82 defined $-[$inx] or next;
63 21         99 $arg{capture} = substr $content, $-[$inx], $+[$inx] - $-[$inx];
64 21         36 last;
65             }
66 24         40 last;
67             }
68             }
69              
70             defined $arg{capture}
71 113 50       249 or confess q{Programming error - reference '},
72             $content, q{' of unknown form};
73              
74 113 50       435 my $self = $class->SUPER::__new( $content, %arg )
75             or return;
76              
77 113         232 $self->{is_named} = $arg{is_named};
78              
79 113         202 my $capture = delete $arg{capture};
80              
81 113 100       356 if ( $self->{is_named} ) {
    100          
82 35         65 $self->{absolute} = undef;
83 35         53 $self->{is_relative} = undef;
84 35         61 $self->{name} = $capture;
85             } elsif ( $capture !~ m/ \A [-+] /smx ) {
86 59         194 $self->{absolute} = $self->{number} = $capture;
87 59         115 $self->{is_relative} = undef;
88             } else {
89 19         44 $self->{number} = $capture;
90 19         34 $self->{is_relative} = 1;
91             }
92              
93 113         279 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 104 my ( $self ) = @_;
108 69         159 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 119 my ( $self ) = @_;
121 87         202 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 8 my ( $self ) = @_;
136 5         21 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 67 my ( $self ) = @_;
161 39         123 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 43 my ( $self ) = @_;
176 22         48 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   111 my ( $self, $number ) = @_;
182 63 50 66     202 if ( ! exists $self->{absolute} && exists $self->{number}
      33        
183             && $self->{number} =~ m/ \A [-+] /smx ) {
184              
185 10         17 my $delta = $self->{number};
186 10 100       34 $delta > 0 and --$delta; # no -0 or +0.
187 10         21 $self->{absolute} = $number + $delta;
188              
189             }
190 63         105 return $number;
191             }
192              
193             1;
194              
195             __END__