File Coverage

blib/lib/String/InterpolatedVariables.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod 1 1 100.0
total 20 20 100.0


line stmt bran cond sub pod time code
1             package String::InterpolatedVariables;
2              
3 2     2   29084 use strict;
  2         4  
  2         63  
4 2     2   10 use warnings;
  2         4  
  2         53  
5              
6 2     2   2104 use Readonly;
  2         7346  
  2         577  
7              
8              
9             =head1 NAME
10              
11             String::InterpolatedVariables - Extract variable names from interpolated strings.
12              
13              
14             =head1 VERSION
15              
16             Version 1.0.4
17              
18             =cut
19              
20             our $VERSION = '1.0.4';
21              
22              
23             =head1 SYNOPSIS
24              
25             use String::InterpolatedVariables;
26              
27             my $variables = String::InterpolatedVariables::extract(
28             'A $test->{string} from a PPI::Token::Quote::Double $object.'
29             );
30              
31             # $variables now contains:
32             # [
33             # '$test->{string}',
34             # '$object',
35             # ]
36              
37              
38             =head1 DESCRIPTION
39              
40             String::InterpolatedVariables offers a way to extract the name of the variables
41             that are present in interpolated strings.
42              
43             This is particularly useful if you are using L to parse Perl documents,
44             and you want to know what variables would be interpolated inside the
45             L and L objects you
46             find there. A practical example of this use can be found in
47             L.
48              
49             =cut
50              
51             Readonly::Scalar my $VARIABLES_REGEX => qr/
52             # Ignore escaped sigils, since those wouldn't get interpreted as variables to interpolate.
53             (?
54             # Allow literal, non-escapy backslashes.
55             (?:\\\\)*
56             (
57             # The variable needs to start with a sigil.
58             [\$\@]
59             # Account for the dereferencing, such as "$$" or "@$".
60             \$?
61             # Variable name.
62             (?:
63             # Note: include '::' to support package variables here.
64             \{(?:\w+|::)\} # Explicit {variable} name.
65             |
66             (?:\w|::)+ # Variable name.
67             )
68             # Catch nested data structures.
69             (?:
70             # Allow for a dereferencing ->.
71             (?:->)?
72             # Can be followed by either a hash or an array.
73             (?:
74             \{(?:\w+|'[^']+'|"[^"]+")\} # Hash element.
75             |
76             \[['"]?\d+['"]?\] # Array element.
77             )
78             )*
79             )
80             /x;
81              
82              
83             =head1 FUNCTIONS
84              
85             =head2 extract()
86              
87             Extract variables from interpolated strings.
88              
89             my $variables = String::InterpolatedVariables::extract(
90             'A $test->{string} from a PPI::Token::Quote::Double $object.'
91             );
92              
93             # $variables now contains:
94             # [
95             # '$test->{string}',
96             # '$object',
97             # ]
98              
99             Note that you need to pass the text of the string, even if the string itself is
100             destined to be interpolated. In other words, passing C<"Test $test"> would not
101             find any variables, as C<$test> would get interpolated by Perl before the
102             string is passed to the C function. This function is thus more
103             useful if you are using using a tool such as L to read Perl code, since
104             PPI will give you access to the text of the string itself for strings that
105             would otherwise be interpolated during execution.
106              
107             =cut
108              
109             sub extract
110             {
111 9     9 1 7042 my ( $string ) = @_;
112              
113 9         17 my $variables = [];
114 9         140 while ( my ( $variable ) = $string =~ $VARIABLES_REGEX )
115             {
116 11         23 push( @$variables, $variable );
117 11         185 $string =~ s/\Q$variable\E//g;
118             }
119              
120 9         24 return $variables;
121             }
122              
123              
124             =head1 BUGS
125              
126             Please report any bugs or feature requests through the web interface at
127             L.
128             I will be notified, and then you'll automatically be notified of progress on
129             your bug as I make changes.
130              
131              
132             =head1 SUPPORT
133              
134             You can find documentation for this module with the perldoc command.
135              
136             perldoc String::InterpolatedVariables
137              
138              
139             You can also look for information at:
140              
141             =over 4
142              
143             =item * GitHub (report bugs there)
144              
145             L
146              
147             =item * AnnoCPAN: Annotated CPAN documentation
148              
149             L
150              
151             =item * CPAN Ratings
152              
153             L
154              
155             =item * MetaCPAN
156              
157             L
158              
159             =back
160              
161              
162             =head1 AUTHOR
163              
164             L,
165             C<< >>.
166              
167              
168             =head1 COPYRIGHT & LICENSE
169              
170             Copyright 2014 Guillaume Aubert.
171              
172             This program is free software: you can redistribute it and/or modify it under
173             the terms of the GNU General Public License version 3 as published by the Free
174             Software Foundation.
175              
176             This program is distributed in the hope that it will be useful, but WITHOUT ANY
177             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
178             PARTICULAR PURPOSE. See the GNU General Public License for more details.
179              
180             You should have received a copy of the GNU General Public License along with
181             this program. If not, see http://www.gnu.org/licenses/
182              
183             =cut
184              
185             1;