← Index
NYTProf Performance Profile   « line view »
For /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/bin/perlcritic
  Run on Sat Mar 19 22:12:22 2016
Reported on Sat Mar 19 22:14:10 2016

Filename/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPI/Token/Magic.pm
StatementsExecuted 366 statements in 1.66ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1111.11ms1.20msPPI::Token::Magic::::BEGIN@46PPI::Token::Magic::BEGIN@46
3411805µs1.61msPPI::Token::Magic::::__TOKENIZER__on_charPPI::Token::Magic::__TOKENIZER__on_char
1347190µs90µsPPI::Token::Magic::::CORE:matchPPI::Token::Magic::CORE:match (opcode)
301189µs89µsPPI::Token::Magic::::CORE:regcompPPI::Token::Magic::CORE:regcomp (opcode)
11156µs56µsPPI::Token::Magic::::BEGIN@49PPI::Token::Magic::BEGIN@49
11111µs23µsPPI::Token::Magic::::BEGIN@44PPI::Token::Magic::BEGIN@44
1117µs45µsPPI::Token::Magic::::BEGIN@48PPI::Token::Magic::BEGIN@48
1113µs3µsPPI::Token::Magic::::BEGIN@45PPI::Token::Magic::BEGIN@45
0000s0sPPI::Token::Magic::::canonicalPPI::Token::Magic::canonical
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package PPI::Token::Magic;
2
3=pod
4
5=head1 NAME
6
7PPI::Token::Magic - Tokens representing magic variables
8
9=head1 INHERITANCE
10
11 PPI::Token::Magic
12 isa PPI::Token::Symbol
13 isa PPI::Token
14 isa PPI::Element
15
16=head1 SYNOPSIS
17
18 # When we say magic variables, we mean these...
19 $1 $2 $3 $4 $5 $6 $7 $8 $9
20 $_ $& $` $' $+ @+ %+ $* $. $/ $|
21 $\\ $" $; $% $= $- @- %- $) $#
22 $~ $^ $: $? $! %! $@ $$ $< $>
23 $( $0 $[ $] @_ @* $} $, $#+ $#-
24 $^L $^A $^E $^C $^D $^F $^H
25 $^I $^M $^N $^O $^P $^R $^S
26 $^T $^V $^W $^X
27
28=head1 DESCRIPTION
29
30C<PPI::Token::Magic> is a sub-class of L<PPI::Token::Symbol> which
31identifies the token as "magic variable", one of the strange and
32unusual variables that are connected to "things" behind the scenes.
33
34Some are extremely common, like C<$_>, and others you will quite
35probably never encounter in your Perl career.
36
37=head1 METHODS
38
39The class provides no additional methods, beyond those provided by it's
40L<PPI::Token::Symbol>, L<PPI::Token> and L<PPI::Element>.
41
42=cut
43
44222µs235µs
# spent 23µs (11+12) within PPI::Token::Magic::BEGIN@44 which was called: # once (11µs+12µs) by PPI::Token::BEGIN@53 at line 44
use strict;
# spent 23µs making 1 call to PPI::Token::Magic::BEGIN@44 # spent 12µs making 1 call to strict::import
45215µs13µs
# spent 3µs within PPI::Token::Magic::BEGIN@45 which was called: # once (3µs+0s) by PPI::Token::BEGIN@53 at line 45
use PPI::Token::Symbol ();
# spent 3µs making 1 call to PPI::Token::Magic::BEGIN@45
46295µs11.20ms
# spent 1.20ms (1.11+88µs) within PPI::Token::Magic::BEGIN@46 which was called: # once (1.11ms+88µs) by PPI::Token::BEGIN@53 at line 46
use PPI::Token::Unknown ();
# spent 1.20ms making 1 call to PPI::Token::Magic::BEGIN@46
47
48271µs282µs
# spent 45µs (7+38) within PPI::Token::Magic::BEGIN@48 which was called: # once (7µs+38µs) by PPI::Token::BEGIN@53 at line 48
use vars qw{$VERSION @ISA %magic};
# spent 45µs making 1 call to PPI::Token::Magic::BEGIN@48 # spent 38µs making 1 call to vars::import
49
# spent 56µs within PPI::Token::Magic::BEGIN@49 which was called: # once (56µs+0s) by PPI::Token::BEGIN@53 at line 70
BEGIN {
501400ns $VERSION = '1.215';
5116µs @ISA = 'PPI::Token::Symbol';
52
53 # Magic variables taken from perlvar.
54 # Several things added separately to avoid warnings.
5515µs foreach ( qw{
56 $1 $2 $3 $4 $5 $6 $7 $8 $9
57 $_ $& $` $' $+ @+ %+ $* $. $/ $|
58 $\\ $" $; $% $= $- @- %- $)
59 $~ $^ $: $? $! %! $@ $$ $< $>
60 $( $0 $[ $] @_ @*
61
62 $^L $^A $^E $^C $^D $^F $^H
63 $^I $^M $^N $^O $^P $^R $^S
64 $^T $^V $^W $^X %^H
65
66 $::|
67 }, '$}', '$,', '$#', '$#+', '$#-' ) {
687033µs $magic{$_} = 1;
69 }
701537µs156µs}
# spent 56µs making 1 call to PPI::Token::Magic::BEGIN@49
71
72=pod
73
74=begin testing __TOKENIZER_on_char 30
75
76my $document = PPI::Document->new(\<<'END_PERL');
77$[; # Magic $[
78$$; # Magic $$
79%-; # Magic %-
80$#-; # Magic $#-
81$$foo; # Symbol $foo Dereference of $foo
82$^W; # Magic $^W
83$^WIDE_SYSTEM_CALLS; # Magic $^WIDE_SYSTEM_CALLS
84${^MATCH}; # Magic ${^MATCH}
85@{^_Bar}; # Magic @{^_Bar}
86${^_Bar}[0]; # Magic @{^_Bar}
87%{^_Baz}; # Magic %{^_Baz}
88${^_Baz}{burfle}; # Magic %{^_Baz}
89$${^MATCH}; # Magic ${^MATCH} Dereference of ${^MATCH}
90\${^MATCH}; # Magic ${^MATCH}
91END_PERL
92
93isa_ok( $document, 'PPI::Document' );
94
95$document->index_locations();
96
97my $symbols = $document->find( 'PPI::Token::Symbol' );
98
99is( scalar(@$symbols), 14, 'Found 14 symbols' );
100my $comments = $document->find( 'PPI::Token::Comment' );
101
102foreach my $token ( @$symbols ) {
103 my ($hash, $class, $name, $remk) =
104 split '\s+', $comments->[$token->line_number - 1], 4;
105 isa_ok( $token, "PPI::Token::$class" );
106 is( $token->symbol, $name, $remk || "The symbol is $name" );
107}
108
109=end testing
110
111=cut
112
113
# spent 1.61ms (805µs+807µs) within PPI::Token::Magic::__TOKENIZER__on_char which was called 34 times, avg 47µs/call: # 34 times (805µs+807µs) by PPI::Tokenizer::_process_next_char at line 554 of PPI/Tokenizer.pm, avg 47µs/call
sub __TOKENIZER__on_char {
1143411µs my $t = $_[1];
115
116 # $c is the candidate new content
1173448µs my $c = $t->{token}->{content} . substr( $t->{line}, $t->{line_cursor}, 1 );
118
119 # Do a quick first test so we don't have to do more than this one.
120 # All of the tests below match this one, so it should provide a
121 # small speed up. This regex should be updated to match the inside
122 # tests if they are changed.
12334175µs5958µs if ( $c =~ /^ \$ .* [ \w : \$ \{ ] $/x ) {
# spent 58µs making 59 calls to PPI::Token::Magic::CORE:match, avg 986ns/call
124
125945µs1811µs if ( $c =~ /^(\$(?:\_[\w:]|::))/ or $c =~ /^\$\'[\w]/ ) {
# spent 11µs making 18 calls to PPI::Token::Magic::CORE:match, avg 589ns/call
126 # If and only if we have $'\d, it is not a
127 # symbol. (this was apparently a concious choice)
128 # Note that $::0 on the other hand is legal
129 if ( $c =~ /^\$\'\d$/ ) {
130 # In this case, we have a magic plus a digit.
131 # Save the CURRENT token, and rerun the on_char
132 return $t->_finalize_token->__TOKENIZER__on_char( $t );
133 }
134
135 # A symbol in the style $_foo or $::foo or $'foo.
136 # Overwrite the current token
137 $t->{class} = $t->{token}->set_class('Symbol');
138 return PPI::Token::Symbol->__TOKENIZER__on_char( $t );
139 }
140
141932µs93µs if ( $c =~ /^\$\$\w/ ) {
# spent 3µs making 9 calls to PPI::Token::Magic::CORE:match, avg 344ns/call
142 # This is really a scalar dereference. ( $$foo )
143 # Add the current token as the cast...
144 $t->{token} = PPI::Token::Cast->new( '$' );
145 $t->_finalize_token;
146
147 # ... and create a new token for the symbol
148 return $t->_new_token( 'Symbol', '$' );
149 }
150
15194µs if ( $c eq '$${' ) {
152 # This _might_ be a dereference of one of the
153 # control-character symbols.
154 my $line = substr $t->{line}, $t->{line_cursor} + 1;
155 if ( $line =~ m/$PPI::Token::Unknown::CURLY_SYMBOL/ ) {
156 # This is really a dereference. ( $${^_foo} )
157 # Add the current token as the cast...
158 $t->{token} = PPI::Token::Cast->new( '$' );
159 $t->_finalize_token;
160
161 # ... and create a new token for the symbol
162 return $t->_new_token( 'Magic', '$' );
163 }
164 }
165
16695µs if ( $c eq '$#$' or $c eq '$#{' ) {
167 # This is really an index dereferencing cast, although
168 # it has the same two chars as the magic variable $#.
16916µs18µs $t->{class} = $t->{token}->set_class('Cast');
# spent 8µs making 1 call to PPI::Token::set_class
17015µs221µs return $t->_finalize_token->__TOKENIZER__on_char( $t );
# spent 19µs making 1 call to PPI::Token::Whitespace::__TOKENIZER__on_char # spent 2µs making 1 call to PPI::Tokenizer::_finalize_token
171 }
172
173837µs85µs if ( $c =~ /^(\$\#)\w/ ) {
# spent 5µs making 8 calls to PPI::Token::Magic::CORE:match, avg 588ns/call
174 # This is really an array index thingy ( $#array )
175322µs39µs $t->{token} = PPI::Token::ArrayIndex->new( "$1" );
# spent 9µs making 3 calls to PPI::Token::new, avg 3µs/call
176319µs6167µs return PPI::Token::ArrayIndex->__TOKENIZER__on_char( $t );
# spent 150µs making 3 calls to PPI::Token::ArrayIndex::__TOKENIZER__on_char, avg 50µs/call # spent 17µs making 3 calls to PPI::Element::DESTROY, avg 6µs/call
177 }
178
179513µs52µs if ( $c =~ /^\$\^\w+$/o ) {
# spent 2µs making 5 calls to PPI::Token::Magic::CORE:match, avg 320ns/call
180 # It's an escaped char magic... maybe ( like $^M )
181 my $next = substr( $t->{line}, $t->{line_cursor}+1, 1 ); # Peek ahead
182 if ($magic{$c} && (!$next || $next !~ /\w/)) {
183 $t->{token}->{content} = $c;
184 $t->{line_cursor}++;
185 } else {
186 # Maybe it's a long magic variable like $^WIDE_SYSTEM_CALLS
187 return 1;
188 }
189 }
190
191514µs52µs if ( $c =~ /^\$\#\{/ ) {
# spent 2µs making 5 calls to PPI::Token::Magic::CORE:match, avg 360ns/call
192 # The $# is actually a case, and { is its block
193 # Add the current token as the cast...
194 $t->{token} = PPI::Token::Cast->new( '$#' );
195 $t->_finalize_token;
196
197 # ... and create a new token for the block
198 return $t->_new_token( 'Structure', '{' );
199 }
200 } elsif ($c =~ /^%\^/) {
201 return 1 if $c eq '%^';
202 # It's an escaped char magic... maybe ( like %^H )
203 if ($magic{$c}) {
204 $t->{token}->{content} = $c;
205 $t->{line_cursor}++;
206 } else {
207 # Back off, treat '%' as an operator
208 chop $t->{token}->{content};
209 bless $t->{token}, $t->{class} = 'PPI::Token::Operator';
210 $t->{line_cursor}--;
211 }
212 }
213
2143019µs if ( $magic{$c} ) {
215 # $#+ and $#-
216 $t->{line_cursor} += length( $c ) - length( $t->{token}->{content} );
217 $t->{token}->{content} = $c;
218 } else {
2193026µs my $line = substr( $t->{line}, $t->{line_cursor} );
22030245µs6099µs if ( $line =~ /($PPI::Token::Unknown::CURLY_SYMBOL)/ ) {
# spent 89µs making 30 calls to PPI::Token::Magic::CORE:regcomp, avg 3µs/call # spent 10µs making 30 calls to PPI::Token::Magic::CORE:match, avg 330ns/call
221 # control character symbol (e.g. ${^MATCH})
222 $t->{token}->{content} .= $1;
223 $t->{line_cursor} += length $1;
224 }
225 }
226
227 # End the current magic token, and recheck
22830148µs60423µs $t->_finalize_token->__TOKENIZER__on_char( $t );
# spent 318µs making 30 calls to PPI::Token::Whitespace::__TOKENIZER__on_char, avg 11µs/call # spent 105µs making 30 calls to PPI::Tokenizer::_finalize_token, avg 4µs/call
229}
230
231# Our version of canonical is plain simple
232sub canonical { $_[0]->content }
233
23412µs1;
235
236=pod
237
238=head1 SUPPORT
239
240See the L<support section|PPI/SUPPORT> in the main module.
241
242=head1 AUTHOR
243
244Adam Kennedy E<lt>adamk@cpan.orgE<gt>
245
246=head1 COPYRIGHT
247
248Copyright 2001 - 2011 Adam Kennedy.
249
250This program is free software; you can redistribute
251it and/or modify it under the same terms as Perl itself.
252
253The full text of the license can be found in the
254LICENSE file included with this module.
255
256=cut
 
# spent 90µs within PPI::Token::Magic::CORE:match which was called 134 times, avg 671ns/call: # 59 times (58µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 123, avg 986ns/call # 30 times (10µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 220, avg 330ns/call # 18 times (11µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 125, avg 589ns/call # 9 times (3µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 141, avg 344ns/call # 8 times (5µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 173, avg 588ns/call # 5 times (2µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 191, avg 360ns/call # 5 times (2µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 179, avg 320ns/call
sub PPI::Token::Magic::CORE:match; # opcode
# spent 89µs within PPI::Token::Magic::CORE:regcomp which was called 30 times, avg 3µs/call: # 30 times (89µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 220, avg 3µs/call
sub PPI::Token::Magic::CORE:regcomp; # opcode