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   72 use strict;
  9         28  
  9         314  
38 9     9   47 use warnings;
  9         17  
  9         231  
39              
40 9     9   45 use base qw{ PPIx::Regexp::Token };
  9         18  
  9         745  
41              
42 9     9   57 use Carp qw{ confess };
  9         18  
  9         516  
43 9     9   58 use List::Util qw{ first };
  9         38  
  9         602  
44 9     9   70 use PPIx::Regexp::Constant qw{ @CARP_NOT };
  9         20  
  9         6858  
45              
46             our $VERSION = '0.087_01';
47              
48             sub __new {
49 113     113   859 my ( $class, $content, %arg ) = @_;
50              
51 113 100       493 if ( defined $arg{capture} ) {
    100          
52             } elsif ( defined $arg{tokenizer} ) {
53 101     116   655 $arg{capture} = first { defined $_ } $arg{tokenizer}->capture();
  116         314  
54             }
55              
56 113 100       542 unless ( defined $arg{capture} ) {
57 24         99 foreach ( $class->__PPIX_TOKEN__recognize() ) {
58 49         80 my ( $re, $a ) = @{ $_ };
  49         99  
59 49 100       334 $content =~ $re or next;
60 24         47 @arg{ keys %{ $a } } = @{ $a }{ keys %{ $a } };
  24         60  
  24         50  
  24         72  
61 24         92 foreach my $inx ( 1 .. $#- ) {
62 34 100       114 defined $-[$inx] or next;
63 21         130 $arg{capture} = substr $content, $-[$inx], $+[$inx] - $-[$inx];
64 21         57 last;
65             }
66 24         45 last;
67             }
68             }
69              
70             defined $arg{capture}
71 113 50       345 or confess q{Programming error - reference '},
72             $content, q{' of unknown form};
73              
74 113 50       544 my $self = $class->SUPER::__new( $content, %arg )
75             or return;
76              
77 113         372 $self->{is_named} = $arg{is_named};
78              
79 113         294 my $capture = delete $arg{capture};
80              
81 113 100       524 if ( $self->{is_named} ) {
    100          
82 35         113 $self->{absolute} = undef;
83 35         82 $self->{is_relative} = undef;
84 35         100 $self->{name} = $capture;
85             } elsif ( $capture !~ m/ \A [-+] /smx ) {
86 59         257 $self->{absolute} = $self->{number} = $capture;
87 59         155 $self->{is_relative} = undef;
88             } else {
89 19         82 $self->{number} = $capture;
90 19         55 $self->{is_relative} = 1;
91             }
92              
93 113         420 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 179 my ( $self ) = @_;
108 69         224 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 239 my ( $self ) = @_;
121 87         283 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 16 my ( $self ) = @_;
136 5         34 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 117 my ( $self ) = @_;
161 39         151 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 60 my ( $self ) = @_;
176 22         63 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   170 my ( $self, $number ) = @_;
182 63 50 66     320 if ( ! exists $self->{absolute} && exists $self->{number}
      33        
183             && $self->{number} =~ m/ \A [-+] /smx ) {
184              
185 10         40 my $delta = $self->{number};
186 10 100       128 $delta > 0 and --$delta; # no -0 or +0.
187 10         47 $self->{absolute} = $number + $delta;
188              
189             }
190 63         179 return $number;
191             }
192              
193             1;
194              
195             __END__