File Coverage

blib/lib/Data/Printer/Common.pm
Criterion Covered Total %
statement 1944 1944 100.0
branch 76 106 71.7
condition 15 29 51.7
subroutine 648 648 100.0
pod 0 2 0.0
total 2683 2729 98.3


line stmt bran cond sub pod time code
1             package Data::Printer::Common;
2             # Private library of shared Data::Printer code.
3 82     82   279807 use strict;
  82         224  
  82         1979  
4 82     82   958 use warnings;
  82         184  
  82         2271  
5 82     82   1303 use Scalar::Util;
  81         180  
  81         67240  
6              
7             my $mro_initialized = 0;
8             my $nsort_initialized;
9              
10              
11             sub _filter_category_for {
12 548     548   1210 my ($name) = @_;
13 548         1126 my %core_types = map { $_ => 1 }
  5628         11091  
14             qw(SCALAR LVALUE ARRAY HASH REF VSTRING GLOB FORMAT Regexp CODE OBJECT);
15 548 100       3193 return exists $core_types{$name} ? 'type_filters' : 'class_filters';
16             }
17              
18             # strings are tough to process: there are control characters like "\t",
19             # unicode characters to name or escape (or do nothing), max_string to
20             # worry about, and every single piece of that could have its own color.
21             # That, and hash keys and strings share this. So we put it all in one place.
22             sub _process_string {
23 266     266   631 my ($ddp, $string, $src_color) = @_;
24              
25             # colorizing messes with reduce_string because we are effectively
26             # adding new (invisible) characters to the string. So we need to
27             # handle reduction first. But! Because we colorize string_max
28             # *and* we should escape any colors already present, we need to
29             # do both at the same time.
30 266         1200 $string = _reduce_string($ddp, $string, $src_color);
31              
32             # now we escape all other control characters except for "\e", which was
33             # already escaped in _reduce_string(), and convert any chosen charset
34             # to the \x{} format. These could go in any particular order:
35 266         852 $string = _escape_chars($ddp, $string, $src_color);
36 266         616 $string = _print_escapes($ddp, $string, $src_color);
37              
38             # finally, send our wrapped string:
39 266         1359 return $ddp->maybe_colorize($string, $src_color);
40             }
41              
42             sub _colorstrip {
43 189     189   623 my ($string) = @_;
44 189         385 $string =~ s{ \e\[ [\d;]* m }{}xmsg;
45 189         1081 return $string;
46             }
47              
48             sub _reduce_string {
49 261     266   3994 my ($ddp, $string, $src_color) = @_;
50 258         617 my $max = $ddp->string_max;
51 258         1033 my $str_len = length($string);
52 261 100 66     2051 if ($max && $str_len && $str_len > $max) {
      100        
53 36         103 my $preserve = $ddp->string_preserve;
54 36 100       527 my $skipped_chars = $str_len - ($preserve eq 'none' ? 0 : $max);
55 38         714 my $skip_message = $ddp->maybe_colorize(
56             $ddp->string_overflow,
57             'caller_info',
58             undef,
59             $src_color
60             );
61 35         100 $skip_message =~ s/__SKIPPED__/$skipped_chars/g;
62 35 100       525 if ($preserve eq 'end') {
    100          
    100          
    100          
63 34         551 substr $string, 0, $skipped_chars, '';
64 32 50       78 $string =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge
  31         488  
65             if $ddp->print_escapes;
66 34         1611 $string = $skip_message . $string;
67             }
68             elsif ($preserve eq 'begin') {
69 33         13661 $string = substr($string, 0, $max);
70 33 50       496 $string =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge
  32         1233  
71             if $ddp->print_escapes;
72 33         2949 $string = $string . $skip_message;
73             }
74             elsif ($preserve eq 'extremes') {
75 33         541 my $leftside_chars = int($max / 2);
76 33         1703 my $rightside_chars = $max - $leftside_chars;
77 33         81 my $leftside = substr($string, 0, $leftside_chars);
78 33         539 my $rightside = substr($string, -$rightside_chars);
79 32 50       232 if ($ddp->print_escapes) {
80 31         73 $leftside =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge;
  31         466  
81 31         218 $rightside =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge;
  31         64  
82             }
83 32         495 $string = $leftside . $skip_message . $rightside;
84             }
85             elsif ($preserve eq 'middle') {
86 31         222 my $string_middle = int($str_len / 2);
87 31         104 my $middle_substr = int($max / 2);
88 31         466 my $substr_begin = $string_middle - $middle_substr;
89 31         218 my $message_begin = $ddp->string_overflow;
90 31         70 $message_begin =~ s/__SKIPPED__/$substr_begin/gs;
91 31         418 my $chars_left = $str_len - ($substr_begin + $max);
92 31         250 my $message_end = $ddp->string_overflow;
93 31         78 $message_end =~ s/__SKIPPED__/$chars_left/gs;
94 31         461 $string = substr($string, $substr_begin, $max);
95 28 50       195 $string =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge
  27         84  
96             if $ddp->print_escapes;
97 28         447 $string = $ddp->maybe_colorize($message_begin, 'caller_info', undef, $src_color)
98             . $string
99             . $ddp->maybe_colorize($message_end, 'caller_info', undef, $src_color)
100             ;
101             }
102             else {
103             # preserving 'none' only shows the skipped message:
104 28         214 $string = $skip_message;
105             }
106             }
107             else {
108             # nothing to do? ok, then escape any colors already present:
109 248 100       629 $string =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge
  28         486  
110             if $ddp->print_escapes;
111             }
112 253         793 return $string;
113             }
114              
115              
116             # _escape_chars() replaces characters with their "escaped" versions.
117             # Because it may be called on scalars or (scalar) hash keys and they
118             # have different colors, we need to be aware of that.
119             sub _escape_chars {
120 253     261   520 my ($ddp, $scalar, $src_color) = @_;
121              
122 253         914 my $escape_kind = $ddp->escape_chars;
123 253         1007 my %target_for = (
124             nonascii => '[^\x{00}-\x{7f}]+',
125             nonlatin1 => '[^\x{00}-\x{ff}]+',
126             );
127              
128 253 100       623 if ($ddp->unicode_charnames) {
    100          
129 30         1424 require charnames;
130 30 100       33261 if ($escape_kind eq 'all') {
131 28         91 $scalar = join('', map { sprintf '\N{%s}', charnames::viacode(ord $_) } split //, $scalar);
  31         677  
132 27         367 $scalar = $ddp->maybe_colorize($scalar, 'escaped');
133             }
134             else {
135 28 50       116 $scalar =~ s{($target_for{$escape_kind})}{$ddp->maybe_colorize( (join '', map { sprintf '\N{%s}', charnames::viacode(ord $_) } split //, $1), 'escaped', undef, $src_color)}ge if exists $target_for{$escape_kind};
  32         462  
  35         691  
136             }
137             }
138             elsif ($escape_kind eq 'all') {
139 27         93 $scalar = join('', map { sprintf '\x{%02x}', ord $_ } split //, $scalar);
  63         451  
140 27         454 $scalar = $ddp->maybe_colorize($scalar, 'escaped');
141             }
142             else {
143 247 100       742 $scalar =~ s{($target_for{$escape_kind})}{$ddp->maybe_colorize((join '', map { sprintf '\x{%02x}', ord $_ } split //, $1), 'escaped', undef, $src_color)}ge if exists $target_for{$escape_kind};
  31         448  
  34         228  
144             }
145 251         748 return $scalar;
146             }
147              
148             # _print_escapes() prints invisible chars if they exist on a string.
149             # Because it may be called on scalars or (scalar) hash keys and they
150             # have different colors, we need to be aware of that. Also, \e is
151             # deliberately omitted because it was escaped from the original
152             # string earlier, and the \e's we have now are our own colorized
153             # output.
154             sub _print_escapes {
155 251     261   838 my ($ddp, $string, $src_color) = @_;
156              
157             # always escape the null character
158 251         683 $string =~ s/\0/$ddp->maybe_colorize('\\0', 'escaped', undef, $src_color)/ge;
  27         76  
159              
160 251 100       877 return $string unless $ddp->print_escapes;
161              
162 26         193 my %escaped = (
163             "\n" => '\n', # line feed
164             "\r" => '\r', # carriage return
165             "\t" => '\t', # horizontal tab
166             "\f" => '\f', # formfeed
167             "\b" => '\b', # backspace
168             "\a" => '\a', # alert (bell)
169             );
170 26         126 foreach my $k ( keys %escaped ) {
171 31         405 $string =~ s/$k/$ddp->maybe_colorize($escaped{$k}, 'escaped', undef, $src_color)/ge;
  31         201  
172             }
173 26         62 return $string;
174             }
175              
176             sub _initialize_nsort {
177 38 50   46   503 return 'Sort::Key::Natural' if $INC{'Sort/Key/Natural.pm'};
178 38 50       740 return 'Sort::Naturally' if $INC{'Sort/Naturally.pm'};
179 35 50       107 return 'Sort::Key::Natural' if !_tryme('use Sort::Key::Natural; 1;');
180 35 50       420 return 'Sort::Naturally' if !_tryme('use Sort::Naturally; 1;');
181 38         742 return 'core';
182             }
183              
184             sub _nsort {
185 157 100   168   405 if (!$nsort_initialized) {
186 33         396 my $nsort_class = _initialize_nsort();
187 36 50       290 if ($nsort_class eq 'Sort::Key::Natural') {
    50          
188 25         76 $nsort_initialized = \&{ $nsort_class . '::natsort' };
  25         411  
189             }
190             elsif ($nsort_class ne 'core') {
191 25         187 $nsort_initialized = \&{ $nsort_class . '::nsort' };
  25         56  
192             }
193             else {
194 36         426 $nsort_initialized = \&_nsort_pp
195             }
196             }
197 160         493 return $nsort_initialized->(@_);
198             }
199              
200             # this is a very simple 'natural-ish' sorter, heavily inspired in
201             # http://www.perlmonks.org/?node_id=657130 by thundergnat and tye
202             sub _nsort_pp {
203 161     169   724 my $i;
204 161         1000 my @unsorted = map lc, @_;
205 161         501 foreach my $data (@unsorted) {
206 82     82   680 no warnings 'uninitialized';
  82         217  
  82         66358  
207 449         1509 $data =~ s/((\.0*)?)(\d+)/("\x0" x length $2) . (pack 'aNa*', 0, length $3, $3)/eg;
  38         511  
208 449         1138 $data .= ' ' . $i++;
209             }
210 161         509 return @_[ map { (split)[-1] } sort @unsorted ];
  449         1900  
211             }
212              
213             sub _fetch_arrayref_of_scalars {
214 25     32   182 my ($props, $name) = @_;
215 25 0 0     124 return [] unless exists $props->{$name} && ref $props->{$name} eq 'ARRAY';
216 25         343 my @valid;
217 25         182 foreach my $option (@{$props->{$name}}) {
  25         51  
218 25 0       394 if (ref $option) {
219             # FIXME: because there is no object at this point, we need to check
220             # the 'warnings' option ourselves.
221             _warn(undef, "'$name' option requires scalar values only. Ignoring $option.")
222 25 0 0     244 if !exists $props->{warnings} || !$props->{warnings};
223 25         137 next;
224             }
225 25         430 push @valid, $option;
226             }
227 25         221 return \@valid;
228             }
229              
230             sub _fetch_anyof {
231 2977     2984   5460 my ($props, $name, $default, $list) = @_;
232 2977 100       9144 return $default unless exists $props->{$name};
233 160         531 foreach my $option (@$list) {
234 329 100       1017 return $option if $props->{$name} eq $option;
235             }
236             _die(
237 25         355 "invalid value '$props->{$name}' for option '$name'"
238             . "(must be one of: " . join(',', @$list) . ")"
239             );
240             };
241              
242              
243             sub _fetch_scalar_or_default {
244 12571     12578   23057 my ($props, $name, $default) = @_;
245 12570 100       38587 return $default unless exists $props->{$name};
246              
247 599 50       1761 if (my $ref = ref $props->{$name}) {
248 23         329 _die("'$name' property must be a scalar, not a reference to $ref");
249             }
250 598         1642 return $props->{$name};
251             }
252              
253             sub _die {
254 25     34   328 my ($message) = @_;
255 25         179 my ($file, $line) = _get_proper_caller();
256 25         91 die '[Data::Printer] ' . $message . " at $file line $line.\n";
257             }
258              
259             sub _warn {
260 23     31   432 my ($ddp, $message) = @_;
261 23 50 33     175 return if $ddp && !$ddp->warnings;
262 23         57 my ($file, $line) = _get_proper_caller();
263 23         326 warn '[Data::Printer] ' . $message . " at $file line $line.\n";
264             }
265              
266             sub _get_proper_caller {
267 25     34   171 my $frame = 1;
268 25         88 while (my @caller = caller($frame++)) {
269 28 100       347 if ($caller[0] !~ /\AD(?:DP|ata::Printer)/) {
270 25         172 return ($caller[1], $caller[2]);
271             }
272             }
273 21         55 return ('n/d', 'n/d');
274             }
275              
276              
277             # simple eval++ adapted from Try::Tiny.
278             # returns a (true) error message if failed.
279             sub _tryme {
280 3379     3388   23371 my ($subref_or_string) = @_;
281              
282 3379         5424 my $previous_error = $@;
283 3379         5205 my ($failed, $error);
284              
285 3379 100       7938 if (ref $subref_or_string eq 'CODE') {
286 345         736 $failed = not eval {
287 345         1065 local $SIG{'__DIE__'}; # make sure we don't trigger any exception hooks.
288 345         893 $@ = $previous_error;
289 345         1052 $subref_or_string->();
290 337         2520 return 1;
291             };
292 345         1428 $error = $@;
293             }
294             else {
295 3055         5320 my $code = q(local $SIG{'__DIE__'};) . $subref_or_string;
296 3055     60 0 235570 $failed = not eval $code;
  39     57 0 15784  
  35     25   16370  
  35     25   647  
  37     25   3619  
  36     25   473  
  36     25   771  
  5     25   12  
  5     25   73  
  5     25   40  
  5     25   21  
  5     25   83  
  5     25   45  
  5     25   27  
  5     25   76  
  5     25   39  
  5     25   11  
  5     24   81  
  5     23   36  
  5     22   13  
  5     22   1037  
  5     21   36  
  5     21   12  
  5     21   67  
  5     21   38  
  5     21   27  
  5     21   68  
  5     21   36  
  5     21   11  
  5     19   66  
  5     19   34  
  5     17   11  
  5     17   100  
  5     16   46  
  5     16   14  
  5     16   104  
  5     16   44  
  5     16   12  
  5     16   80  
  5     16   34  
  5     16   12  
  5     5   75  
  5     5   36  
  5     5   12  
  5     5   78  
  5     5   39  
  5     5   17  
  5     5   84  
  5     5   40  
  5     5   12  
  5     5   92  
  5     5   41  
  5     5   11  
  5     5   73  
  5     5   39  
  5     5   10  
  5     5   79  
  5     5   37  
  5     5   41  
  5     5   92  
  5     5   35  
  5     5   19  
  5     5   134  
  5     5   49  
  5     5   23  
  5     5   69  
  5     5   39  
  5     5   11  
  5     5   79  
  5     5   36  
  5     5   12  
  5     5   72  
  5     5   54  
  5     5   13  
  5     5   84  
  5     5   49  
  5     5   20  
  5     5   69  
  5     5   35  
  5     5   11  
  5     5   64  
  5     5   39  
  5     5   15  
  5     5   72  
  5     5   43  
  5     5   16  
  5     5   100  
  5     5   43  
  5     5   12  
  5     5   72  
  5     5   47  
  5     5   26  
  5     5   83  
  5     4   40  
  5     4   15  
  5     4   70  
  5     4   44  
  5     4   15  
  5     4   81  
  5     4   37  
  5     4   17  
  5     4   80  
  5     4   45  
  5     4   18  
  5     4   66  
  5     4   38  
  5     4   20  
  5     4   71  
  5     4   34  
  5     4   12  
  5     4   64  
  5     4   36  
  5     4   15  
  5     4   66  
  5     4   34  
  5     3   13  
  5     3   61  
  5     3   963  
  5     3   11  
  5     3   76  
  5     3   36  
  5     3   13  
  5     3   81  
  4     3   31  
  4     3   10  
  4     3   57  
  4     3   32  
  4     3   8  
  4     3   53  
  4     3   30  
  4     3   13  
  4     3   55  
  4     3   29  
  4     3   8  
  4     3   53  
  4     3   37  
  4     3   9  
  4     3   55  
  4     3   30  
  4     3   10  
  4     3   58  
  4     3   27  
  4     3   9  
  4     3   52  
  4     3   29  
  4     3   12  
  4     3   74  
  4     3   28  
  4     3   10  
  4     3   55  
  4     3   28  
  4     3   9  
  4     3   61  
  4     3   30  
  4     3   12  
  4     3   60  
  4     3   217  
  4     3   155  
  4     3   66  
  4     3   33  
  4     3   12  
  4     3   66  
  4     3   29  
  4     3   40  
  4     3   62  
  4     3   32  
  4     3   10  
  4     3   58  
  4     3   28  
  4     3   9  
  4     3   50  
  4     3   28  
  4     3   9  
  4     3   62  
  4     3   28  
  4     3   12  
  4     3   65  
  4     3   27  
  4     3   10  
  4     3   58  
  4     3   28  
  4     3   10  
  4     3   52  
  4     3   31  
  4     3   11  
  4     3   1008  
  4     3   27  
  4     3   9  
  4     3   78  
  3     3   21  
  3     3   8  
  3     3   42  
  3     3   25  
  3     3   17  
  3     3   50  
  3     3   22  
  3     3   10  
  3     3   49  
  3     3   22  
  3     3   8  
  3     3   41  
  3     3   20  
  3     3   18  
  3     3   46  
  3     3   22  
  3     3   10  
  3     3   44  
  3     3   32  
  3     3   12  
  3     3   42  
  3     3   32  
  3     3   7  
  3     3   51  
  3     2   22  
  3     2   15  
  3     2   54  
  3     2   20  
  3     2   23  
  3     2   51  
  3     2   21  
  3     2   7  
  3     2   40  
  3     2   21  
  3     2   10  
  3     2   38  
  3     2   21  
  3     2   7  
  3     2   42  
  3     2   22  
  3     2   6  
  3     2   73  
  3     2   25  
  3     2   7  
  3     2   42  
  3     2   22  
  3     2   7  
  3     2   41  
  3     2   21  
  3     2   8  
  3     2   44  
  3     2   22  
  3     2   8  
  3     2   42  
  3     2   22  
  3     2   17  
  3     2   42  
  3     2   21  
  3     2   6  
  3     2   41  
  3     2   20  
  3     2   9  
  3     2   40  
  3     2   21  
  3     2   7  
  3     2   45  
  3     2   42  
  3     2   13  
  3     2   38  
  3     2   20  
  3     2   8  
  3     2   40  
  3     2   24  
  3     2   8  
  3     2   43  
  3     2   23  
  3     2   8  
  3     2   51  
  3     2   22  
  3     2   7  
  3     2   49  
  3     2   22  
  3     2   8  
  3     2   40  
  3     2   23  
  3     2   8  
  3     1   40  
  3     1   23  
  3     1   8  
  3     1   43  
  3     1   21  
  3     1   7  
  3     1   39  
  3     1   20  
  3     1   9  
  3     1   51  
  3     1   19  
  3     1   6  
  3     1   55  
  3     1   21  
  3     1   7  
  3     1   39  
  3     1   30  
  3     1   127  
  3     1   44  
  3     1   19  
  3     1   7  
  3     1   40  
  3     1   21  
  3     1   7  
  3     1   52  
  3     1   21  
  3     1   8  
  3     1   41  
  3     1   23  
  3     1   7  
  3     1   41  
  3     1   22  
  3     1   8  
  3     1   42  
  3     1   21  
  3     1   9  
  3     1   43  
  3     1   24  
  3     1   8  
  3     1   42  
  3     1   21  
  3     1   8  
  3     1   40  
  3     1   21  
  3     1   7  
  3     1   43  
  3     1   20  
  3     1   8  
  3     1   36  
  3     1   22  
  3     1   6  
  3     1   38  
  3     1   21  
  3     1   6  
  3     1   51  
  3     1   30  
  3     1   6  
  3     1   38  
  3     1   23  
  3     1   21  
  3     1   48  
  3     1   29  
  3     1   7  
  3     1   41  
  3     1   26  
  3     1   9  
  3     1   41  
  3     1   24  
  3     1   7  
  3     1   59  
  3     1   31  
  3     1   16  
  3     1   45  
  3     1   22  
  3     1   6  
  3     1   51  
  3     1   23  
  3     1   7  
  3     1   47  
  3     1   22  
  3     1   7  
  3     1   53  
  3     1   21  
  3     1   7  
  3     1   49  
  3     1   56  
  3     1   9  
  3     1   47  
  3     1   20  
  3     1   7  
  3     1   39  
  3     1   22  
  3     1   9  
  3     1   38  
  3     1   23  
  3     1   10  
  3     1   42  
  3     1   27  
  3     1   9  
  3     1   53  
  3     1   22  
  3     1   12  
  3     1   42  
  3     1   29  
  3     1   8  
  3     1   52  
  3     1   24  
  3     1   7  
  3     1   46  
  3     1   22  
  3     1   6  
  3     1   42  
  3     1   23  
  3     1   7  
  3     1   44  
  3     1   27  
  3     1   7  
  3     1   40  
  3     1   26  
  3     1   8  
  3     1   39  
  3     1   20  
  3     1   13  
  3     1   39  
  3     1   27  
  3     1   6  
  3     1   43  
  3     1   21  
  3     1   6  
  3     1   40  
  3     1   21  
  3     1   8  
  3     1   41  
  3     1   21  
  3     1   11  
  3     1   60  
  3     1   24  
  3     1   10  
  3     1   44  
  3     1   22  
  3     1   12  
  3     1   51  
  3     1   34  
  3     1   9  
  3     1   59  
  3     1   29  
  3     1   9  
  3     1   42  
  3     1   23  
  3     1   8  
  3     1   39  
  3     1   22  
  3     1   11  
  3     1   41  
  3     1   23  
  3     1   13  
  3     1   42  
  3     1   28  
  3     1   28  
  3     1   70  
  3     1   21  
  3     1   7  
  3     1   47  
  3     1   21  
  3     1   14  
  3     1   44  
  3     1   29  
  3     1   10  
  3     1   66  
  3     1   21  
  3     1   8  
  3     1   40  
  3     1   21  
  3     1   8  
  3     1   42  
  3     1   21  
  3     1   7  
  3     1   43  
  3     1   24  
  3     1   9  
  3     1   55  
  3     1   27  
  3     1   9  
  3     1   44  
  3     1   21  
  3     1   7  
  3     1   44  
  3     1   26  
  3     1   8  
  3     1   54  
  3     1   23  
  3     1   24  
  3     1   46  
  3     1   22  
  3     1   9  
  3     1   46  
  3     1   22  
  3     1   13  
  3     1   37  
  3     1   22  
  3     1   9  
  3     1   50  
  3     1   32  
  3     1   10  
  3     1   61  
  3     1   28  
  3     1   9  
  3     1   42  
  2     1   13  
  2     1   9  
  2     1   31  
  2     1   15  
  2     1   12  
  2     1   32  
  2     1   24  
  2     1   15  
  2     1   33  
  2     1   14  
  2     1   16  
  2     1   37  
  2     1   20  
  2     1   8  
  2     1   46  
  2     1   13  
  2     1   7  
  2     1   48  
  2     1   14  
  2     1   7  
  2     1   38  
  2     1   19  
  2     1   5  
  2     1   34  
  2     1   13  
  2     1   11  
  2     1   27  
  2     1   15  
  2     1   13  
  2     1   41  
  2     1   15  
  2     1   16  
  2     1   37  
  2     1   15  
  2     1   6  
  2     1   32  
  2     1   14  
  2     1   5  
  2     1   28  
  2     1   15  
  2     1   5  
  2     1   24  
  2     1   16  
  2     1   7  
  2     1   29  
  2     1   16  
  2     1   7  
  2     1   32  
  2     1   23  
  2     1   5  
  2     1   28  
  2     1   15  
  2     1   6  
  2     1   47  
  2     1   14  
  2     1   6  
  2     1   32  
  2     1   23  
  2     1   6  
  2     1   25  
  2     1   17  
  2     1   5  
  2     1   30  
  2     1   16  
  2     1   5  
  2     1   29  
  2     1   14  
  2     1   5  
  2     1   27  
  2     1   14  
  2     1   11  
  2     1   29  
  2     1   15  
  2     1   4  
  2     1   26  
  2     1   14  
  2     1   8  
  2     1   44  
  2     1   14  
  2     1   5  
  2     1   31  
  2     1   16  
  2     1   5  
  2     1   30  
  2     1   25  
  2     1   6  
  2     1   30  
  2     1   14  
  2     1   4  
  2     1   29  
  2     1   19  
  2     1   4  
  2     1   30  
  2     1   20  
  2     1   6  
  2     1   32  
  2     1   14  
  2     1   4  
  2     1   27  
  2     1   27  
  2     1   11  
  2     1   26  
  2     1   14  
  2     1   4  
  2     1   27  
  2     1   20  
  2     1   5  
  2     1   26  
  2     1   15  
  2     1   5  
  2     1   30  
  2     1   13  
  2     1   6  
  2     1   28  
  2     1   16  
  2     1   7  
  2     1   28  
  2     1   15  
  2     1   5  
  2     1   30  
  2     1   14  
  2     1   5  
  2     1   49  
  2     1   15  
  2     1   5  
  2     1   37  
  2     1   14  
  2     1   5  
  2     1   24  
  2     1   13  
  2     1   6  
  2     1   27  
  2     1   18  
  2     1   7  
  2     1   59  
  2     1   15  
  2         9  
  2         39  
  2         19  
  2         5  
  2         32  
  2         15  
  2         6  
  2         33  
  2         13  
  2         6  
  2         29  
  2         15  
  2         8  
  2         38  
  2         26  
  2         10  
  2         33  
  2         25  
  2         5  
  2         35  
  2         16  
  2         4  
  2         31  
  2         16  
  2         12  
  2         30  
  2         14  
  2         5  
  2         27  
  2         14  
  2         4  
  2         38  
  2         16  
  2         6  
  2         29  
  2         21  
  2         7  
  2         32  
  2         17  
  2         12  
  2         56  
  2         21  
  2         7  
  2         30  
  2         24  
  2         5  
  2         31  
  2         14  
  2         6  
  2         31  
  1         7  
  1         3  
  1         14  
  1         7  
  1         3  
  1         13  
  1         7  
  1         3  
  1         13  
  1         8  
  1         2  
  1         13  
  1         40  
  1         4  
  1         26  
  1         7  
  1         2  
  1         14  
  1         8  
  1         2  
  1         14  
  1         8  
  1         2  
  1         13  
  1         8  
  1         2  
  1         16  
  1         9  
  1         2  
  1         15  
  1         8  
  1         3  
  1         14  
  1         7  
  1         3  
  1         13  
  1         7  
  1         3  
  1         14  
  1         9  
  1         2  
  1         21  
  1         8  
  1         2  
  1         14  
  1         7  
  1         3  
  1         20  
  1         7  
  1         3  
  1         14  
  1         7  
  1         3  
  1         12  
  1         7  
  1         2  
  1         13  
  1         7  
  1         2  
  1         13  
  1         8  
  1         3  
  1         16  
  1         7  
  1         2  
  1         16  
  1         8  
  1         5  
  1         15  
  1         8  
  1         3  
  1         28  
  1         8  
  1         3  
  1         15  
  1         14  
  1         3  
  1         16  
  1         10  
  1         2  
  1         13  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         45  
  1         12  
  1         2  
  1         14  
  1         7  
  1         2  
  1         14  
  1         7  
  1         3  
  1         12  
  1         7  
  1         4  
  1         15  
  1         14  
  1         4  
  1         14  
  1         7  
  1         3  
  1         14  
  1         8  
  1         2  
  1         14  
  1         7  
  1         2  
  1         14  
  1         8  
  1         2  
  1         13  
  1         8  
  1         3  
  1         26  
  1         7  
  1         3  
  1         11  
  1         14  
  1         3  
  1         12  
  1         7  
  1         2  
  1         19  
  1         7  
  1         3  
  1         13  
  1         7  
  1         3  
  1         28  
  1         9  
  1         11  
  1         16  
  1         8  
  1         7  
  1         15  
  1         7  
  1         2  
  1         14  
  1         8  
  1         2  
  1         14  
  1         9  
  1         4  
  1         15  
  1         8  
  1         2  
  1         13  
  1         9  
  1         3  
  1         26  
  1         10  
  1         2  
  1         13  
  1         8  
  1         3  
  1         13  
  1         7  
  1         2  
  1         13  
  1         6  
  1         3  
  1         13  
  1         7  
  1         3  
  1         12  
  1         9  
  1         2  
  1         16  
  1         8  
  1         2  
  1         16  
  1         8  
  1         3  
  1         13  
  1         9  
  1         3  
  1         13  
  1         8  
  1         2  
  1         13  
  1         8  
  1         6  
  1         13  
  1         7  
  1         3  
  1         15  
  1         6  
  1         8  
  1         12  
  1         7  
  1         2  
  1         13  
  1         7  
  1         2  
  1         21  
  1         6  
  1         2  
  1         13  
  1         7  
  1         2  
  1         23  
  1         8  
  1         2  
  1         19  
  1         9  
  1         2  
  1         16  
  1         10  
  1         2  
  1         15  
  1         7  
  1         2  
  1         14  
  1         7  
  1         2  
  1         17  
  1         8  
  1         2  
  1         14  
  1         18  
  1         2  
  1         13  
  1         6  
  1         3  
  1         13  
  1         7  
  1         6  
  1         14  
  1         7  
  1         3  
  1         13  
  1         8  
  1         2  
  1         13  
  1         11  
  1         3  
  1         13  
  1         10  
  1         2  
  1         15  
  1         8  
  1         2  
  1         15  
  1         8  
  1         3  
  1         15  
  1         7  
  1         3  
  1         13  
  1         7  
  1         2  
  1         13  
  1         7  
  1         4  
  1         16  
  1         7  
  1         2  
  1         12  
  1         7  
  1         3  
  1         12  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         14  
  1         8  
  1         2  
  1         12  
  1         7  
  1         2  
  1         14  
  1         10  
  1         3  
  1         18  
  1         8  
  1         4  
  1         15  
  1         7  
  1         3  
  1         27  
  1         8  
  1         3  
  1         14  
  1         7  
  1         4  
  1         13  
  1         20  
  1         3  
  1         15  
  1         7  
  1         2  
  1         20  
  1         12  
  1         2  
  1         14  
  1         15  
  1         9  
  1         15  
  1         6  
  1         3  
  1         14  
  1         7  
  1         3  
  1         13  
  1         7  
  1         3  
  1         43  
  1         9  
  1         3  
  1         16  
  1         8  
  1         3  
  1         16  
  1         7  
  1         2  
  1         27  
  1         10  
  1         2  
  1         14  
  1         8  
  1         2  
  1         13  
  1         8  
  1         6  
  1         13  
  1         7  
  1         3  
  1         14  
  1         7  
  1         2  
  1         28  
  1         7  
  1         4  
  1         13  
  1         7  
  1         2  
  1         24  
  1         7  
  1         2  
  1         13  
  1         7  
  1         2  
  1         13  
  1         10  
  1         3  
  1         15  
  1         10  
  1         2  
  1         16  
  1         9  
  1         2  
  1         14  
  1         6  
  1         2  
  1         14  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         13  
  1         7  
  1         3  
  1         16  
  1         8  
  1         2  
  1         52  
  1         6  
  1         2  
  1         13  
  1         7  
  1         2  
  1         14  
  1         7  
  1         2  
  1         16  
  1         7  
  1         2  
  1         13  
  1         16  
  1         3  
  1         16  
  1         7  
  1         4  
  1         15  
  1         7  
  1         3  
  1         19  
  1         14  
  1         4  
  1         16  
  1         7  
  1         2  
  1         14  
  1         7  
  1         2  
  1         15  
  1         7  
  1         3  
  1         13  
  1         7  
  1         2  
  1         15  
  1         14  
  1         2  
  1         13  
  1         6  
  1         2  
  1         14  
  1         7  
  1         2  
  1         13  
  1         9  
  1         3  
  1         13  
  1         7  
  1         3  
  1         15  
  1         12  
  1         2  
  1         15  
  1         8  
  1         3  
  1         16  
  1         8  
  1         2  
  1         14  
  1         7  
  1         3  
  1         13  
  1         7  
  1         4  
  1         14  
  1         8  
  1         2  
  1         14  
  1         12  
  1         2  
  1         15  
  1         13  
  1         4  
  1         13  
  1         7  
  1         8  
  1         17  
  1         17  
  1         3  
  1         13  
  1         7  
  1         2  
  1         13  
  1         8  
  1         3  
  1         17  
  1         8  
  1         2  
  1         16  
  1         12  
  1         3  
  1         19  
  1         7  
  1         2  
  1         14  
  1         7  
  1         2  
  1         13  
  1         8  
  1         3  
  1         12  
  1         7  
  1         3  
  1         13  
  1         7  
  1         2  
  1         17  
  1         8  
  1         2  
  1         13  
  1         6  
  1         3  
  1         13  
  1         7  
  1         2  
  1         12  
  1         6  
  1         3  
  1         12  
  1         8  
  1         2  
  1         16  
  1         9  
  1         4  
  1         21  
  1         6  
  1         3  
  1         28  
  1         7  
  1         4  
  1         13  
  1         7  
  1         2  
  1         13  
  1         8  
  1         2  
  1         14  
  1         7  
  1         2  
  1         17  
  1         15  
  1         6  
  1         16  
  1         7  
  1         2  
  1         13  
  1         8  
  1         4  
  1         14  
  1         13  
  1         3  
  1         12  
  1         10  
  1         3  
  1         15  
  1         7  
  1         3  
  1         14  
  1         9  
  1         3  
  1         14  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         13  
  1         7  
  1         2  
  1         12  
  1         9  
  1         2  
  1         13  
  1         10  
  1         2  
  1         13  
  1         7  
  1         3  
  1         24  
  1         6  
  1         9  
  1         12  
  1         7  
  1         4  
  1         13  
  1         7  
  1         3  
  1         13  
  1         8  
  1         5  
  1         26  
  1         8  
  1         2  
  1         15  
  1         19  
  1         3  
  1         15  
  1         8  
  1         2  
  1         25  
  1         8  
  1         2  
  1         15  
  1         7  
  1         2  
  1         15  
  1         8  
  1         2  
  1         12  
  1         6  
  1         3  
  1         12  
  1         7  
  1         3  
  1         14  
  1         6  
  1         3  
  1         13  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         13  
  1         7  
  1         2  
  1         12  
  1         8  
  1         2  
  1         15  
  1         8  
  1         5  
  1         15  
  1         8  
  1         3  
  1         17  
  1         7  
  1         2  
  1         15  
  1         9  
  1         3  
  1         13  
  1         7  
  1         2  
  1         14  
  1         7  
  1         2  
  1         13  
  1         7  
  1         2  
  1         12  
  1         6  
  1         3  
  1         13  
  1         8  
  1         2  
  1         14  
  1         7  
  1         3  
  1         14  
  1         7  
  1         3  
  1         13  
  1         9  
  1         2  
  1         17  
  1         8  
  1         2  
  1         16  
  1         8  
  1         2  
  1         15  
  1         7  
  1         3  
  1         14  
  1         8  
  1         3  
  1         14  
  1         7  
  1         4  
  1         17  
  1         7  
  1         3  
  1         14  
  1         7  
  1         12  
  1         15  
  1         7  
  1         5  
  1         12  
  1         6  
  1         3  
  1         12  
  1         6  
  1         5  
  1         13  
  1         6  
  1         4  
  1         13  
  1         8  
  1         2  
  1         16  
  1         7  
  1         4  
  1         16  
  1         7  
  1         2  
  1         16  
  1         7  
  1         2  
  1         14  
  1         7  
  1         2  
  1         23  
  1         8  
  1         2  
  1         13  
  1         8  
  1         3  
  1         13  
  1         16  
  1         7  
  1         13  
  1         7  
  1         11  
  1         18  
  1         7  
  1         2  
  1         13  
  1         7  
  1         4  
  1         12  
  1         7  
  1         2  
  1         14  
  1         8  
  1         4  
  1         16  
  1         8  
  1         4  
  1         15  
  1         7  
  1         4  
  1         13  
  1         7  
  1         3  
  1         15  
  1         8  
  1         2  
  1         14  
  1         7  
  1         3  
  1         13  
  1         7  
  1         2  
  1         15  
  1         7  
  1         3  
  1         14  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         13  
  1         7  
  1         3  
  1         12  
  1         16  
  1         2  
  1         15  
  1         8  
  1         3  
  1         15  
  1         8  
  1         2  
  1         16  
  1         7  
  1         3  
  1         14  
  1         8  
  1         3  
  1         15  
  1         7  
  1         4  
  1         13  
  1         7  
  1         3  
  1         15  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         14  
  1         7  
  1         2  
  1         13  
  1         8  
  1         2  
  1         13  
  1         6  
  1         4  
  1         15  
  1         7  
  1         2  
  1         12  
  1         9  
  1         3  
  1         20  
  1         9  
  1         7  
  1         15  
  1         8  
  1         3  
  1         15  
  1         7  
  1         3  
  1         15  
  1         9  
  1         3  
  1         14  
  1         7  
  1         4  
  1         13  
  1         10  
  1         3  
  1         13  
  1         8  
  1         2  
  1         13  
  1         9  
  1         3  
  1         12  
  1         7  
  1         2  
  1         12  
  1         10  
  1         3  
  1         14  
  1         7  
  1         2  
  1         30  
  1         8  
  1         3  
  1         16  
  1         8  
  1         3  
  1         16  
  1         7  
  1         3  
  1         15  
  1         7  
  1         3  
  1         13  
  1         6  
  1         3  
  1         13  
  1         15  
  1         4  
  1         16  
  1         7  
  1         2  
  1         26  
  1         464  
  1         5  
  1         300  
  1         7  
  1         3  
  1         14  
  1         7  
  1         2  
  1         12  
  1         6  
  1         5  
  1         12  
  1         6  
  1         2  
  1         13  
  1         10  
  1         3  
  1         16  
  1         7  
  1         2  
  1         14  
  1         7  
  1         3  
  1         12  
  1         7  
  1         2  
  1         13  
  1         6  
  1         4  
  1         13  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         12  
  1         6  
  1         3  
  1         12  
  1         6  
  1         5  
  1         13  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         13  
  1         7  
  1         2  
  1         12  
  1         8  
  1         3  
  1         14  
  1         8  
  1         2  
  1         14  
  1         8  
  1         3  
  1         13  
  1         7  
  1         2  
  1         13  
  1         7  
  1         2  
  1         13  
  1         7  
  1         2  
  1         14  
  1         12  
  1         2  
  1         14  
  1         7  
  1         2  
  1         19  
  1         7  
  1         2  
  1         12  
  1         8  
  1         2  
  1         13  
  1         7  
  1         3  
  1         12  
  1         7  
  1         2  
  1         13  
  1         8  
  1         2  
  1         18  
  1         8  
  1         3  
  1         14  
  1         7  
  1         4  
  1         14  
  1         7  
  1         2  
  1         14  
  1         7  
  1         3  
  1         15  
  1         7  
  1         3  
  1         26  
  1         6  
  1         3  
  1         13  
  1         7  
  1         3  
  1         15  
  1         7  
  1         2  
  1         12  
  1         7  
  1         2  
  1         15  
  1         15  
  1         4  
  1         133  
  1         9  
  1         2  
  1         15  
  1         8  
  1         2  
  1         16  
  1         9  
  1         4  
  1         15  
  1         8  
  1         3  
  1         14  
  1         7  
  1         2  
  1         14  
  1         8  
  1         2  
  1         13  
  1         6  
  1         3  
  1         13  
  1         7  
  1         2  
  1         12  
  1         7  
  1         2  
  1         13  
  1         7  
  1         2  
  1         13  
  1         7  
  1         2  
  1         13  
  1         7  
  1         2  
  1         12  
  1         6  
  1         3  
  1         12  
  1         7  
  1         3  
  1         16  
  1         8  
  1         2  
  1         15  
  1         7  
  1         14  
  1         17  
  1         8  
  1         2  
  1         14  
  1         8  
  1         2  
  1         13  
  1         7  
  1         3  
  1         13  
  1         7  
  1         2  
  1         15  
  1         7  
  1         2  
  1         11  
  1         7  
  1         2  
  1         12  
  1         7  
  1         2  
  1         14  
  1         8  
  1         3  
  1         12  
  1         7  
  1         2  
  1         45  
297 3055         8075 $error = $@;
298             }
299 3379         5630 $@ = $previous_error;
300             # at this point $failed contains a true value if the eval died,
301             # even if some destructor overwrote $@ as the eval was unwinding.
302 3379 100       11842 return unless $failed;
303 60   50     509 return ($error || '(unknown error)');
304             }
305              
306              
307             # When printing array elements or hash keys, we may traverse all of it
308             # or just a few chunks. This function returns those chunks' indexes, and
309             # a scalar ref to a message whenever a chunk was skipped.
310             sub _fetch_indexes_for {
311 135     141   440 my ($array_ref, $prefix, $ddp) = @_;
312              
313 135         313 my $max_function = $prefix . '_max';
314 135         551 my $preserve_function = $prefix . '_preserve';
315 133         349 my $overflow_function = $prefix . '_overflow';
316 133         417 my $max = $ddp->$max_function;
317 133         678 my $preserve = $ddp->$preserve_function;
318              
319 133 100 100     734 return (0 .. $#{$array_ref}) if !$max || @$array_ref <= $max;
  121         529  
320              
321 31         344 my $skip_message = $ddp->maybe_colorize($ddp->$overflow_function, 'overflow');
322 29 100 100     362 if ($preserve eq 'begin' || $preserve eq 'end') {
    100          
    100          
323 22         50 my $n_elements = @$array_ref - $max;
324 22         273 $skip_message =~ s/__SKIPPED__/$n_elements/g;
325             return $preserve eq 'begin'
326             ? ((0 .. ($max - 1)), \$skip_message)
327 23 100       338 : (\$skip_message, ($n_elements .. $#{$array_ref}))
  18         50  
328             ;
329             }
330             elsif ($preserve eq 'extremes') {
331 18         251 my $half_max = int($max / 2);
332 18         305 my $last_index_of_chunk_one = $half_max - 1;
333 17         41 my $n_elements = @$array_ref - $max;
334              
335 17         227 my $first_index_of_chunk_two = @$array_ref - ($max - $half_max);
336 18         269 $skip_message =~ s/__SKIPPED__/$n_elements/g;
337             return (
338             (0 .. $last_index_of_chunk_one),
339             \$skip_message,
340 17         42 ($first_index_of_chunk_two .. $#{$array_ref})
  17         257  
341             );
342             }
343             elsif ($preserve eq 'middle') {
344 18         130 my $array_middle = int($#{$array_ref} / 2);
  18         48  
345 18         261 my $first_index_to_show = $array_middle - int($max / 2);
346 18         122 my $last_index_to_show = $first_index_to_show + $max - 1;
347 18         41 my ($message_begin, $message_end) = ($skip_message, $skip_message);
348 18         241 $message_begin =~ s/__SKIPPED__/$first_index_to_show/gse;
  18         128  
349 18         48 my $items_left = $#{$array_ref} - $last_index_to_show;
  18         226  
350 18         120 $message_end =~ s/__SKIPPED__/$items_left/gs;
351             return (
352 18         72 \$message_begin,
353             $first_index_to_show .. $last_index_to_show,
354             \$message_end
355             );
356             }
357             else { # $preserve eq 'none'
358 18         234 my $n_elements = scalar(@$array_ref);
359 18         143 $skip_message =~ s/__SKIPPED__/$n_elements/g;
360 18         51 return (\$skip_message);
361             }
362             }
363              
364             # helpers below strongly inspired by the excellent Package::Stash:
365             sub _linear_ISA_for {
366 160     171   547 my ($class, $ddp) = @_;
367 160 100       493 _initialize_mro($ddp) unless $mro_initialized;
368 160         240 my $isa;
369 160 50       549 if ($mro_initialized > 0) {
370 149         545 $isa = mro::get_linear_isa($class);
371             }
372             else {
373             # minimal fallback in case Class::MRO isn't available
374             # (should only matter for perl < 5.009_005):
375 5         12 $isa = [ $class, _get_superclasses_for($class) ];
376             }
377 149 100       440 return [@$isa, ($ddp->class->universal ? 'UNIVERSAL' : ())];
378             }
379              
380             sub _initialize_mro {
381 16     38   65 my ($ddp) = @_;
382             my $error = _tryme(sub {
383 16 50   38   262 if ($] < 5.009_005) { require MRO::Compat }
  5         40  
384 16         92 else { require mro }
385 16         171 1;
386 16         111 });
387 16 0 33     169 if ($error && index($error, 'in @INC') != -1 && $mro_initialized == 0) {
      33        
388 5 0       11 _warn(
389             $ddp,
390             ($] < 5.009_005 ? 'MRO::Compat' : 'mro') . ' not found in @INC.'
391             . ' Objects may display inaccurate/incomplete ISA and method list'
392             );
393             }
394 16 50       117 $mro_initialized = $error ? -1 : 1;
395             }
396              
397             sub _get_namespace {
398 113     135   231 my ($class_name) = @_;
399 113         163 my $namespace;
400             {
401 82     82   654 no strict 'refs';
  82         206  
  82         10016  
  113         239  
402 113         189 $namespace = \%{ $class_name . '::' }
  113         297  
403             }
404             # before 5.10, stashes don't ever seem to drop to a refcount of zero,
405             # so weakening them isn't helpful
406 113 50       465 Scalar::Util::weaken($namespace) if $] >= 5.010;
407              
408 113         297 return $namespace;
409             }
410              
411             sub _get_superclasses_for {
412 43     64   116 my ($class_name) = @_;
413 43         157 my $namespace = _get_namespace($class_name);
414 43         129 my $res = _get_symbol($class_name, $namespace, 'ISA', 'ARRAY');
415 43 100       68 return @{ $res || [] };
  43         266  
416             }
417              
418             sub _get_symbol {
419 267     288   512 my ($class_name, $namespace, $symbol_name, $symbol_kind) = @_;
420              
421 267 100       510 if (exists $namespace->{$symbol_name}) {
422 252         441 my $entry_ref = \$namespace->{$symbol_name};
423 252 50       1267 if (ref($entry_ref) eq 'GLOB') {
424 252         335 return *{$entry_ref}{$symbol_kind};
  252         778  
425             }
426             else {
427 5 0       36 if ($symbol_kind eq 'CODE') {
428 82     82   635 no strict 'refs';
  82         217  
  82         4382  
429 5         11 return \&{ $class_name . '::' . $symbol_name };
  5         86  
430             }
431             }
432             }
433 20         73 return;
434             }
435              
436             1;