File Coverage

blib/lib/Data/Printer/Common.pm
Criterion Covered Total %
statement 1980 1980 100.0
branch 76 106 71.7
condition 16 29 55.1
subroutine 660 660 100.0
pod 0 4 0.0
total 2732 2779 98.3


line stmt bran cond sub pod time code
1             package Data::Printer::Common;
2             # Private library of shared Data::Printer code.
3 83     83   443997 use strict;
  83         176  
  83         2667  
4 83     83   1181 use warnings;
  83         184  
  83         3426  
5 83     83   2365 use Scalar::Util;
  82         222  
  82         80815  
6              
7             my $mro_initialized = 0;
8             my $nsort_initialized;
9              
10              
11             sub _filter_category_for {
12 550     550   1311 my ($name) = @_;
13 550         1233 my %core_types = map { $_ => 1 }
  5630         24225  
14             qw(SCALAR LVALUE ARRAY HASH REF VSTRING GLOB FORMAT Regexp CODE OBJECT);
15 550 100       7613 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 279     279   670 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 279         1540 $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 279         1019 $string = _escape_chars($ddp, $string, $src_color);
36 279         820 $string = _print_escapes($ddp, $string, $src_color);
37              
38             # finally, send our wrapped string:
39 279         1623 return $ddp->maybe_colorize($string, $src_color);
40             }
41              
42             sub _colorstrip {
43 195     195   621 my ($string) = @_;
44 195         399 $string =~ s{ \e\[ [\d;]* m }{}xmsg;
45 195         1278 return $string;
46             }
47              
48             sub _reduce_string {
49 274     279   4775 my ($ddp, $string, $src_color) = @_;
50 271         806 my $max = $ddp->string_max;
51 271         1427 my $str_len = length($string);
52 274 100 100     2165 if ($max && $str_len && $str_len > $max) {
      100        
53 38         167 my $preserve = $ddp->string_preserve;
54 38 100       666 my $skipped_chars = $str_len - ($preserve eq 'none' ? 0 : $max);
55 40         627 my $skip_message = $ddp->maybe_colorize(
56             $ddp->string_overflow,
57             'caller_info',
58             undef,
59             $src_color
60             );
61 37         102 $skip_message =~ s/__SKIPPED__/$skipped_chars/g;
62 37 100       678 if ($preserve eq 'end') {
    100          
    100          
    100          
63 36         433 substr $string, 0, $skipped_chars, '';
64 34 50       80 $string =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge
  33         825  
65             if $ddp->print_escapes;
66 36         2464 $string = $skip_message . $string;
67             }
68             elsif ($preserve eq 'begin') {
69 35         452434 $string = substr($string, 0, $max);
70 35 50       604 $string =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge
  35         7192  
71             if $ddp->print_escapes;
72 35         2262 $string = $string . $skip_message;
73             }
74             elsif ($preserve eq 'extremes') {
75 35         611 my $leftside_chars = int($max / 2);
76 35         1432 my $rightside_chars = $max - $leftside_chars;
77 35         80 my $leftside = substr($string, 0, $leftside_chars);
78 35         598 my $rightside = substr($string, -$rightside_chars);
79 34 50       220 if ($ddp->print_escapes) {
80 33         196 $leftside =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge;
  33         627  
81 33         233 $rightside =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge;
  33         72  
82             }
83 34         585 $string = $leftside . $skip_message . $rightside;
84             }
85             elsif ($preserve eq 'middle') {
86 33         209 my $string_middle = int($str_len / 2);
87 33         81 my $middle_substr = int($max / 2);
88 33         519 my $substr_begin = $string_middle - $middle_substr;
89 33         246 my $message_begin = $ddp->string_overflow;
90 33         74 $message_begin =~ s/__SKIPPED__/$substr_begin/gs;
91 33         570 my $chars_left = $str_len - ($substr_begin + $max);
92 33         245 my $message_end = $ddp->string_overflow;
93 33         74 $message_end =~ s/__SKIPPED__/$chars_left/gs;
94 33         540 $string = substr($string, $substr_begin, $max);
95 30 50       237 $string =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge
  29         76  
96             if $ddp->print_escapes;
97 30         549 $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 30         208 $string = $skip_message;
105             }
106             }
107             else {
108             # nothing to do? ok, then escape any colors already present:
109 261 100       846 $string =~ s{\e}{$ddp->maybe_colorize('\\e', 'escaped', undef, $src_color)}ge
  30         580  
110             if $ddp->print_escapes;
111             }
112 266         888 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 266     274   652 my ($ddp, $scalar, $src_color) = @_;
121              
122 266         1276 my $escape_kind = $ddp->escape_chars;
123 266         1307 my %target_for = (
124             nonascii => '[^\x{00}-\x{7f}]+',
125             nonlatin1 => '[^\x{00}-\x{ff}]+',
126             );
127              
128 266 100       722 if ($ddp->unicode_charnames) {
    100          
129 32         1397 require charnames;
130 32 100       8355 if ($escape_kind eq 'all') {
131 30         65 $scalar = join('', map { sprintf '\N{%s}', charnames::viacode(ord $_) } split //, $scalar);
  33         864  
132 29         309 $scalar = $ddp->maybe_colorize($scalar, 'escaped');
133             }
134             else {
135 30 50       141 $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};
  34         481  
  36         666  
136             }
137             }
138             elsif ($escape_kind eq 'all') {
139 28         67 $scalar = join('', map { sprintf '\x{%02x}', ord $_ } split //, $scalar);
  64         533  
140 28         694 $scalar = $ddp->maybe_colorize($scalar, 'escaped');
141             }
142             else {
143 260 100       509596 $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};
  33         417  
  36         8105  
144             }
145 264         915 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 264     274   938 my ($ddp, $string, $src_color) = @_;
156              
157             # always escape the null character
158 264         10652 $string =~ s/\0/$ddp->maybe_colorize('\\0', 'escaped', undef, $src_color)/ge;
  29         76  
159              
160 264 100       1140 return $string unless $ddp->print_escapes;
161              
162 28         197 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 28         126 foreach my $k ( keys %escaped ) {
171 33         530 $string =~ s/$k/$ddp->maybe_colorize($escaped{$k}, 'escaped', undef, $src_color)/ge;
  33         199  
172             }
173 28         72 return $string;
174             }
175              
176             sub _initialize_nsort {
177 41 50   49   342501 return 'Sort::Key::Natural' if $INC{'Sort/Key/Natural.pm'};
178 41 50       767 return 'Sort::Naturally' if $INC{'Sort/Naturally.pm'};
179 38 50       105 return 'Sort::Key::Natural' if !_tryme('use Sort::Key::Natural; 1;');
180 38 50       550 return 'Sort::Naturally' if !_tryme('use Sort::Naturally; 1;');
181 41         625 return 'core';
182             }
183              
184             sub _nsort {
185 171 100   182   411 if (!$nsort_initialized) {
186 36         506 my $nsort_class = _initialize_nsort();
187 39 50       264 if ($nsort_class eq 'Sort::Key::Natural') {
    50          
188 27         59 $nsort_initialized = \&{ $nsort_class . '::natsort' };
  27         508  
189             }
190             elsif ($nsort_class ne 'core') {
191 27         203 $nsort_initialized = \&{ $nsort_class . '::nsort' };
  27         55  
192             }
193             else {
194 39         508 $nsort_initialized = \&_nsort_pp
195             }
196             }
197 174         578 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 175     183   964 my $i;
204 175         1402 my @unsorted = map lc, @_;
205 175         557 foreach my $data (@unsorted) {
206 83     83   800 no warnings 'uninitialized';
  83         177  
  83         79449  
207 486         1911 $data =~ s/((\.0*)?)(\d+)/("\x0" x length $2) . (pack 'aNa*', 0, length $3, $3)/eg;
  40         597  
208 486         1219 $data .= ' ' . $i++;
209             }
210 175         604 return @_[ map { (split)[-1] } sort @unsorted ];
  486         2243  
211             }
212              
213             sub _fetch_arrayref_of_scalars {
214 27     35   204 my ($props, $name) = @_;
215 27 0 0     59 return [] unless exists $props->{$name} && ref $props->{$name} eq 'ARRAY';
216 27         464 my @valid;
217 27         197 foreach my $option (@{$props->{$name}}) {
  27         64  
218 27 0       607 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 27 0 0     313 if !exists $props->{warnings} || !$props->{warnings};
223 27         63 next;
224             }
225 27         463 push @valid, $option;
226             }
227 26         173 return \@valid;
228             }
229              
230             sub _fetch_anyof {
231 3086     3094   6630 my ($props, $name, $default, $list) = @_;
232 3086 100       11912 return $default unless exists $props->{$name};
233 160         655 foreach my $option (@$list) {
234 329 100       1239 return $option if $props->{$name} eq $option;
235             }
236             _die(
237 25         429 "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 13030     13039   26039 my ($props, $name, $default) = @_;
245 13029 100       48922 return $default unless exists $props->{$name};
246              
247 611 50       2131 if (my $ref = ref $props->{$name}) {
248 24         862 _die("'$name' property must be a scalar, not a reference to $ref");
249             }
250 611         1962 return $props->{$name};
251             }
252              
253             sub _die {
254 26     36   487 my ($message) = @_;
255 26         177 my ($file, $line) = _get_proper_caller();
256 26         88 die '[Data::Printer] ' . $message . " at $file line $line.\n";
257             }
258              
259             sub _warn {
260 24     33   146470 my ($ddp, $message) = @_;
261 24 50 33     176 return if $ddp && !$ddp->warnings;
262 24         52 my ($file, $line) = _get_proper_caller();
263 24         489 warn '[Data::Printer] ' . $message . " at $file line $line.\n";
264             }
265              
266             sub _get_proper_caller {
267 26     36   172 my $frame = 1;
268 26         116 while (my @caller = caller($frame++)) {
269 29 100       474 if ($caller[0] !~ /\AD(?:DP|ata::Printer)/) {
270 26         200 return ($caller[1], $caller[2]);
271             }
272             }
273 22         54 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 3508     3518   1312575 my ($subref_or_string) = @_;
281              
282 3508         6128 my $previous_error = $@;
283 3508         7070 my ($failed, $error);
284              
285 3508 100       9349 if (ref $subref_or_string eq 'CODE') {
286 358         880 $failed = not eval {
287 358         1456 local $SIG{'__DIE__'}; # make sure we don't trigger any exception hooks.
288 358         1076 $@ = $previous_error;
289 358         1189 $subref_or_string->();
290 350         3157 return 1;
291             };
292 358         1819 $error = $@;
293             }
294             else {
295 3172         5621 my $code = q(local $SIG{'__DIE__'};) . $subref_or_string;
296 3172     62 0 317183 $failed = not eval $code;
  40     60 0 21834  
  36     27 0 16348  
  35     27 0 754  
  38     27   4805  
  37     27   639  
  37     27   1455  
  5     27   9  
  5     27   79  
  5     27   36  
  5     27   12  
  5     27   106  
  5     27   50  
  5     27   12  
  5     27   93  
  5     26   40  
  5     25   11  
  5     24   93  
  5     24   39  
  5     23   13  
  5     23   122  
  5     22   80  
  5     22   14  
  5     22   89  
  5     22   35  
  5     22   10  
  5     22   82  
  5     22   36  
  5     22   11  
  5     20   82  
  5     20   35  
  5     18   13  
  5     18   102  
  5     17   38  
  5     17   9  
  5     17   109  
  5     17   38  
  5     17   13  
  5     17   88  
  5     17   38  
  5     17   10  
  5     6   116  
  5     6   38  
  5     6   13  
  5     5   85  
  5     5   40  
  5     5   12  
  5     5   121  
  5     5   57  
  5     5   13  
  5     5   92  
  5     5   38  
  5     5   27  
  5     5   98  
  5     5   37  
  5     5   12  
  5     5   86  
  5     5   38  
  5     5   12  
  5     5   84  
  5     5   35  
  5     5   11  
  5     5   79  
  5     5   34  
  5     5   12  
  5     5   81  
  5     5   37  
  5     5   9  
  5     5   127  
  5     5   37  
  5     5   12  
  5     5   93  
  5     5   38  
  5     5   12  
  5     5   101  
  5     5   40  
  5     5   12  
  5     5   93  
  5     5   54  
  5     5   12  
  5     5   94  
  5     5   40  
  5     5   13  
  5     5   146  
  5     5   46  
  5     5   12  
  5     5   103  
  5     5   43  
  5     5   13  
  5     5   115  
  5     5   44  
  5     5   12  
  5     5   103  
  5     4   47  
  5     4   12  
  5     4   100  
  5     4   44  
  5     4   12  
  5     4   118  
  5     4   41  
  5     4   12  
  5     4   103  
  5     4   51  
  5     4   12  
  5     4   92  
  5     4   43  
  5     4   11  
  5     4   101  
  5     4   38  
  5     4   13  
  5     4   93  
  5     4   41  
  5     4   13  
  5     4   87  
  5     4   73  
  5     3   12  
  5     3   101  
  5     3   43  
  5     3   13  
  5     3   98  
  5     3   42  
  5     3   12  
  5     3   130  
  4     3   33  
  4     3   11  
  4     3   119  
  4     3   35  
  4     3   12  
  4     3   77  
  4     3   34  
  4     3   10  
  4     3   106  
  4     3   65  
  4     3   13  
  4     3   82  
  4     3   32  
  4     3   12  
  4     3   76  
  4     3   33  
  4     3   12  
  4     3   87  
  4     3   30  
  4     3   12  
  4     3   73  
  4     3   41  
  4     3   12  
  4     3   91  
  4     3   33  
  4     3   11  
  4     3   76  
  4     3   33  
  4     3   10  
  4     3   75  
  4     3   36  
  4     3   10  
  4     3   82  
  4     3   34  
  4     3   11  
  4     3   79  
  4     3   52  
  4     3   10  
  4     3   83  
  4     3   38  
  4     3   10  
  4     3   78  
  4     3   36  
  4     3   8  
  4     3   79  
  4     3   35  
  4     3   10  
  4     3   111  
  4     3   34  
  4     3   11  
  4     3   75  
  4     3   33  
  4     3   9  
  4     3   71  
  4     3   34  
  4     3   10  
  4     3   71  
  4     3   35  
  4     3   10  
  4     3   73  
  4     3   34  
  4     3   9  
  4     3   86  
  4     3   34  
  4     3   11  
  4     3   73  
  3     3   25  
  3     3   8  
  3     3   64  
  3     3   26  
  3     3   72  
  3     3   66  
  3     3   27  
  3     3   10  
  3     3   81  
  3     3   54  
  3     3   11  
  3     3   59  
  3     3   31  
  3     3   8  
  3     3   83  
  3     3   29  
  3     3   9  
  3     3   63  
  3     3   26  
  3     3   7  
  3     3   78  
  3     3   26  
  3     3   8  
  3     3   57  
  3     2   26  
  3     2   7  
  3     2   57  
  3     2   27  
  3     2   8  
  3     2   57  
  3     2   26  
  3     2   9  
  3     2   56  
  3     2   27  
  3     2   10  
  3     2   57  
  3     2   28  
  3     2   9  
  3     2   58  
  3     2   27  
  3     2   9  
  3     2   79  
  3     2   28  
  3     2   9  
  3     2   66  
  3     2   28  
  3     2   8  
  3     2   62  
  3     2   27  
  3     2   9  
  3     2   63  
  3     2   27  
  3     2   8  
  3     2   62  
  3     2   27  
  3     2   8  
  3     2   62  
  3     2   27  
  3     2   9  
  3     2   64  
  3     2   26  
  3     2   7  
  3     2   56  
  3     2   25  
  3     2   8  
  3     2   58  
  3     2   26  
  3     2   8  
  3     2   112  
  3     2   26  
  3     2   7  
  3     2   55  
  3     2   24  
  3     2   8  
  3     2   59  
  3     2   27  
  3     2   8  
  3     2   69  
  3     2   26  
  3     2   7  
  3     2   63  
  3     2   26  
  3     2   7  
  3     2   89  
  3     2   26  
  3     2   7  
  3     1   63  
  3     1   26  
  3     1   7  
  3     1   122  
  3     1   28  
  3     1   7  
  3     1   91  
  3     1   28  
  3     1   7  
  3     1   56  
  3     1   27  
  3     1   8  
  3     1   56  
  3     1   27  
  3     1   7  
  3     1   59  
  3     1   26  
  3     1   7  
  3     1   57  
  3     1   27  
  3     1   10  
  3     1   53  
  3     1   26  
  3     1   8  
  3     1   60  
  3     1   24  
  3     1   10  
  3     1   55  
  3     1   27  
  3     1   8  
  3     1   68  
  3     1   28  
  3     1   10  
  3     1   59  
  3     1   26  
  3     1   7  
  3     1   63  
  3     1   28  
  3     1   8  
  3     1   59  
  3     1   25  
  3     1   8  
  3     1   58  
  3     1   24  
  3     1   61  
  3     1   91  
  3     1   25  
  3     1   8  
  3     1   76  
  3     1   27  
  3     1   8  
  3     1   61  
  3     1   27  
  3     1   8  
  3     1   58  
  3     1   24  
  3     1   9  
  3     1   83  
  3     1   27  
  3     1   8  
  3     1   59  
  3     1   27  
  3     1   11  
  3     1   79  
  3     1   26  
  3     1   8  
  3     1   57  
  3     1   25  
  3     1   9  
  3     1   56  
  3     1   26  
  3     1   9  
  3     1   59  
  3     1   26  
  3     1   9  
  3     1   92  
  3     1   25  
  3     1   8  
  3     1   59  
  3     1   24  
  3     1   8  
  3     1   58  
  3     1   24  
  3     1   8  
  3     1   56  
  3     1   24  
  3     1   8  
  3     1   85  
  3     1   26  
  3     1   9  
  3     1   87  
  3     1   24  
  3     1   6  
  3     1   60  
  3     1   25  
  3     1   8  
  3     1   68  
  3     1   28  
  3     1   9  
  3     1   62  
  3     1   25  
  3     1   8  
  3     1   193  
  3     1   27  
  3     1   7  
  3     1   63  
  3     1   24  
  3     1   8  
  3     1   59  
  3     1   26  
  3     1   8  
  3     1   62  
  3     1   26  
  3     1   6  
  3     1   60  
  3     1   26  
  3     1   10  
  3     1   58  
  3     1   26  
  3     1   8  
  3     1   60  
  3     1   26  
  3     1   7  
  3     1   71  
  3     1   29  
  3     1   6  
  3     1   61  
  3     1   73  
  3     1   11  
  3     1   74  
  3     1   26  
  3     1   10  
  3     1   78  
  3     1   29  
  3     1   7  
  3     1   77  
  3     1   27  
  3     1   9  
  3     1   77  
  3     1   27  
  3     1   8  
  3     1   91  
  3     1   27  
  3     1   8  
  3     1   61  
  3     1   28  
  3     1   56  
  3     1   84  
  3     1   49  
  3     1   9  
  3     1   70  
  3     1   27  
  3     1   9  
  3     1   62  
  3     1   27  
  3     1   7  
  3     1   60  
  3     1   26  
  3     1   9  
  3     1   57  
  3     1   27  
  3     1   8  
  3     1   71  
  3     1   38  
  3     1   8  
  3     1   62  
  3     1   29  
  3     1   9  
  3     1   1663  
  3     1   27  
  3     1   7  
  3     1   59  
  3     1   24  
  3     1   7  
  3     1   60  
  3     1   30  
  3     1   10  
  3     1   92  
  3     1   29  
  3     1   11  
  3     1   67  
  3     1   28  
  3     1   9  
  3     1   67  
  3     1   25  
  3     1   9  
  3     1   64  
  3     1   26  
  3     1   6  
  3     1   59  
  3     1   26  
  3     1   9  
  3     1   75  
  3     1   28  
  3     1   9  
  3     1   60  
  3     1   31  
  3     1   9  
  3     1   61  
  3     1   26  
  3     1   12  
  3     1   60  
  3     1   27  
  3     1   8  
  3     1   163  
  3     1   48  
  3     1   17  
  3     1   65  
  2     1   16  
  2     1   6  
  2     1   38  
  2     1   53  
  2     1   8  
  2     1   39  
  2     1   17  
  2     1   5  
  2     1   36  
  2     1   12  
  2     1   4  
  2     1   34  
  2     1   12  
  2     1   5  
  2     1   31  
  2     1   12  
  2     1   4  
  2     1   37  
  2     1   13  
  2     1   5  
  2     1   33  
  2     1   13  
  2     1   17  
  2     1   34  
  2     1   14  
  2     1   4  
  2     1   31  
  2     1   12  
  2     1   5  
  2     1   30  
  2     1   13  
  2     1   5  
  2     1   32  
  2     1   15  
  2     1   5  
  2     1   31  
  2     1   15  
  2     1   4  
  2     1   31  
  2     1   14  
  2     1   5  
  2     1   28  
  2     1   18  
  2     1   8  
  2     1   42  
  2     1   16  
  2     1   4  
  2     1   34  
  2     1   15  
  2     1   5  
  2     1   32  
  2     1   14  
  2     1   4  
  2     1   36  
  2     1   14  
  2     1   5  
  2     1   29  
  2     1   14  
  2     1   4  
  2     1   31  
  2     1   31  
  2     1   5  
  2     1   31  
  2     1   14  
  2     1   4  
  2     1   27  
  2     1   17  
  2     1   5  
  2     1   39  
  2     1   14  
  2     1   4  
  2     1   34  
  2     1   14  
  2     1   3  
  2     1   46  
  2     1   14  
  2     1   4  
  2     1   31  
  2     1   18  
  2     1   4  
  2     1   39  
  2     1   20  
  2     1   5  
  2     1   42  
  2     1   18  
  2     1   4  
  2     1   39  
  2     1   18  
  2     1   7  
  2     1   48  
  2     1   12  
  2     1   4  
  2     1   31  
  2     1   15  
  2     1   268  
  2     1   41  
  2     1   14  
  2     1   17  
  2     1   32  
  2     1   14  
  2     1   4  
  2     1   30  
  2     1   12  
  2     1   4  
  2     1   62  
  2     1   14  
  2     1   3  
  2     1   33  
  2     1   14  
  2     1   4  
  2     1   31  
  2     1   14  
  2     1   5  
  2     1   29  
  2     1   16  
  2     1   5  
  2     1   34  
  2     1   14  
  2     1   4  
  2     1   34  
  2     1   14  
  2     1   4  
  2     1   29  
  2     1   14  
  2     1   4  
  2     1   30  
  2     1   15  
  2     1   4  
  2     1   29  
  2     1   13  
  2     1   11  
  2     1   33  
  2     1   14  
  2     1   4  
  2     1   30  
  2     1   13  
  2     1   3  
  2     1   28  
  2     1   15  
  2     1   4  
  2     1   42  
  2     1   13  
  2     1   5  
  2     1   31  
  2     1   14  
  2     1   4  
  2     1   32  
  2     1   32  
  2         4  
  2         32  
  2         14  
  2         5  
  2         37  
  2         18  
  2         6  
  2         42  
  2         14  
  2         3  
  2         84  
  2         18  
  2         5  
  2         62  
  2         17  
  2         4  
  2         41  
  2         17  
  2         4  
  2         40  
  2         15  
  2         3  
  2         37  
  2         15  
  2         5  
  2         35  
  2         12  
  2         4  
  2         33  
  2         13  
  2         5  
  2         33  
  2         14  
  2         3  
  2         33  
  2         13  
  2         5  
  2         208  
  1         10  
  1         3  
  1         19  
  1         9  
  1         3  
  1         21  
  1         9  
  1         3  
  1         22  
  1         9  
  1         3  
  1         21  
  1         9  
  1         3  
  1         37  
  1         9  
  1         2  
  1         21  
  1         9  
  1         2  
  1         20  
  1         9  
  1         3  
  1         20  
  1         9  
  1         30  
  1         28  
  1         9  
  1         3  
  1         23  
  1         9  
  1         3  
  1         22  
  1         10  
  1         3  
  1         18  
  1         10  
  1         3  
  1         20  
  1         10  
  1         2  
  1         21  
  1         9  
  1         3  
  1         22  
  1         9  
  1         3  
  1         21  
  1         9  
  1         3  
  1         20  
  1         9  
  1         2  
  1         19  
  1         9  
  1         2  
  1         21  
  1         27  
  1         3  
  1         22  
  1         10  
  1         4  
  1         24  
  1         9  
  1         3  
  1         403  
  1         11  
  1         3  
  1         22  
  1         10  
  1         3  
  1         22  
  1         9  
  1         2  
  1         21  
  1         7  
  1         2  
  1         20  
  1         8  
  1         2  
  1         18  
  1         8  
  1         3  
  1         18  
  1         9  
  1         2  
  1         21  
  1         9  
  1         3  
  1         19  
  1         8  
  1         2  
  1         20  
  1         11  
  1         2  
  1         20  
  1         9  
  1         3  
  1         23  
  1         11  
  1         3  
  1         25  
  1         9  
  1         2  
  1         22  
  1         9  
  1         3  
  1         50  
  1         8  
  1         3  
  1         21  
  1         8  
  1         2  
  1         17  
  1         10  
  1         2  
  1         24  
  1         9  
  1         3  
  1         21  
  1         9  
  1         3  
  1         21  
  1         10  
  1         3  
  1         36  
  1         9  
  1         2  
  1         20  
  1         9  
  1         3  
  1         20  
  1         9  
  1         3  
  1         23  
  1         27  
  1         3  
  1         23  
  1         8  
  1         3  
  1         20  
  1         9  
  1         3  
  1         19  
  1         37  
  1         4  
  1         22  
  1         10  
  1         3  
  1         20  
  1         9  
  1         2  
  1         19  
  1         8  
  1         4  
  1         20  
  1         9  
  1         2  
  1         19  
  1         10  
  1         3  
  1         20  
  1         8  
  1         3  
  1         42  
  1         9  
  1         3  
  1         19  
  1         9  
  1         2  
  1         20  
  1         9  
  1         3  
  1         22  
  1         9  
  1         3  
  1         23  
  1         9  
  1         2  
  1         41  
  1         10  
  1         4  
  1         20  
  1         9  
  1         2  
  1         21  
  1         10  
  1         3  
  1         52  
  1         9  
  1         3  
  1         19  
  1         9  
  1         2  
  1         18  
  1         9  
  1         2  
  1         20  
  1         9  
  1         3  
  1         19  
  1         8  
  1         3  
  1         20  
  1         40  
  1         3  
  1         25  
  1         9  
  1         2  
  1         21  
  1         8  
  1         3  
  1         94  
  1         8  
  1         3  
  1         19  
  1         8  
  1         3  
  1         17  
  1         8  
  1         2  
  1         18  
  1         8  
  1         15  
  1         20  
  1         8  
  1         2  
  1         17  
  1         8  
  1         2  
  1         18  
  1         9  
  1         3  
  1         21  
  1         8  
  1         3  
  1         19  
  1         8  
  1         2  
  1         17  
  1         10  
  1         3  
  1         22  
  1         9  
  1         2  
  1         20  
  1         7  
  1         3  
  1         17  
  1         10  
  1         2  
  1         19  
  1         8  
  1         3  
  1         35  
  1         8  
  1         2  
  1         18  
  1         7  
  1         3  
  1         15  
  1         8  
  1         3  
  1         30  
  1         8  
  1         2  
  1         16  
  1         9  
  1         3  
  1         18  
  1         8  
  1         3  
  1         17  
  1         8  
  1         2  
  1         16  
  1         8  
  1         3  
  1         21  
  1         10  
  1         3  
  1         23  
  1         10  
  1         3  
  1         21  
  1         9  
  1         3  
  1         20  
  1         10  
  1         2  
  1         19  
  1         10  
  1         32  
  1         23  
  1         9  
  1         3  
  1         20  
  1         8  
  1         3  
  1         20  
  1         8  
  1         2  
  1         18  
  1         8  
  1         3  
  1         18  
  1         9  
  1         3  
  1         21  
  1         10  
  1         2  
  1         21  
  1         9  
  1         3  
  1         21  
  1         9  
  1         3  
  1         25  
  1         10  
  1         3  
  1         24  
  1         9  
  1         3  
  1         42  
  1         9  
  1         2  
  1         22  
  1         9  
  1         2  
  1         20  
  1         8  
  1         4  
  1         21  
  1         9  
  1         3  
  1         21  
  1         10  
  1         2  
  1         21  
  1         9  
  1         3  
  1         21  
  1         9  
  1         3  
  1         20  
  1         8  
  1         3  
  1         20  
  1         11  
  1         3  
  1         24  
  1         10  
  1         3  
  1         24  
  1         10  
  1         2  
  1         23  
  1         10  
  1         3  
  1         21  
  1         9  
  1         3  
  1         21  
  1         9  
  1         2  
  1         21  
  1         9  
  1         3  
  1         21  
  1         8  
  1         3  
  1         20  
  1         9  
  1         2  
  1         22  
  1         9  
  1         3  
  1         22  
  1         9  
  1         3  
  1         20  
  1         10  
  1         3  
  1         21  
  1         9  
  1         3  
  1         53  
  1         11  
  1         3  
  1         25  
  1         9  
  1         3  
  1         22  
  1         10  
  1         2  
  1         21  
  1         10  
  1         3  
  1         22  
  1         30  
  1         3  
  1         22  
  1         8  
  1         3  
  1         20  
  1         8  
  1         3  
  1         18  
  1         8  
  1         3  
  1         18  
  1         10  
  1         2  
  1         37  
  1         9  
  1         3  
  1         19  
  1         9  
  1         3  
  1         19  
  1         9  
  1         3  
  1         24  
  1         10  
  1         3  
  1         23  
  1         10  
  1         3  
  1         21  
  1         9  
  1         2  
  1         22  
  1         10  
  1         3  
  1         20  
  1         9  
  1         3  
  1         20  
  1         9  
  1         3  
  1         20  
  1         10  
  1         2  
  1         21  
  1         10  
  1         2  
  1         19  
  1         9  
  1         3  
  1         19  
  1         9  
  1         3  
  1         22  
  1         9  
  1         2  
  1         19  
  1         9  
  1         3  
  1         21  
  1         9  
  1         4  
  1         23  
  1         10  
  1         3  
  1         23  
  1         9  
  1         3  
  1         41  
  1         9  
  1         3  
  1         21  
  1         9  
  1         3  
  1         20  
  1         10  
  1         2  
  1         56  
  1         10  
  1         2  
  1         20  
  1         9  
  1         3  
  1         19  
  1         10  
  1         2  
  1         20  
  1         9  
  1         3  
  1         20  
  1         9  
  1         3  
  1         20  
  1         10  
  1         3  
  1         24  
  1         9  
  1         3  
  1         23  
  1         9  
  1         3  
  1         20  
  1         9  
  1         3  
  1         20  
  1         9  
  1         2  
  1         21  
  1         10  
  1         3  
  1         22  
  1         9  
  1         3  
  1         20  
  1         9  
  1         2  
  1         19  
  1         10  
  1         3  
  1         21  
  1         8  
  1         3  
  1         39  
  1         9  
  1         3  
  1         20  
  1         10  
  1         4  
  1         20  
  1         9  
  1         4  
  1         21  
  1         11  
  1         3  
  1         53  
  1         9  
  1         2  
  1         39  
  1         10  
  1         3  
  1         20  
  1         9  
  1         3  
  1         19  
  1         9  
  1         3  
  1         19  
  1         10  
  1         2  
  1         20  
  1         8  
  1         3  
  1         20  
  1         8  
  1         2  
  1         21  
  1         9  
  1         3  
  1         19  
  1         10  
  1         2  
  1         36  
  1         9  
  1         3  
  1         21  
  1         9  
  1         3  
  1         23  
  1         8  
  1         4  
  1         24  
  1         9  
  1         3  
  1         21  
  1         11  
  1         3  
  1         21  
  1         8  
  1         3  
  1         38  
  1         9  
  1         4  
  1         21  
  1         8  
  1         3  
  1         20  
  1         10  
  1         3  
  1         51  
  1         8  
  1         2  
  1         19  
  1         9  
  1         2  
  1         22  
  1         8  
  1         2  
  1         19  
  1         9  
  1         3  
  1         19  
  1         8  
  1         3  
  1         20  
  1         9  
  1         3  
  1         21  
  1         8  
  1         2  
  1         18  
  1         10  
  1         3  
  1         17  
  1         8  
  1         2  
  1         16  
  1         8  
  1         3  
  1         19  
  1         9  
  1         14  
  1         22  
  1         7  
  1         3  
  1         16  
  1         8  
  1         2  
  1         16  
  1         7  
  1         3  
  1         16  
  1         8  
  1         3  
  1         17  
  1         10  
  1         3  
  1         28  
  1         9  
  1         3  
  1         21  
  1         8  
  1         4  
  1         19  
  1         8  
  1         3  
  1         17  
  1         8  
  1         3  
  1         17  
  1         8  
  1         2  
  1         18  
  1         8  
  1         2  
  1         30  
  1         8  
  1         3  
  1         16  
  1         34  
  1         5  
  1         18  
  1         7  
  1         2  
  1         16  
  1         7  
  1         3  
  1         17  
  1         7  
  1         3  
  1         17  
  1         8  
  1         3  
  1         16  
  1         8  
  1         4  
  1         24  
  1         10  
  1         2  
  1         23  
  1         9  
  1         3  
  1         20  
  1         7  
  1         4  
  1         16  
  1         7  
  1         2  
  1         15  
  1         8  
  1         2  
  1         19  
  1         9  
  1         3  
  1         17  
  1         8  
  1         4  
  1         19  
  1         8  
  1         3  
  1         19  
  1         8  
  1         3  
  1         18  
  1         10  
  1         3  
  1         21  
  1         8  
  1         3  
  1         37  
  1         10  
  1         4  
  1         25  
  1         10  
  1         2  
  1         22  
  1         9  
  1         3  
  1         19  
  1         9  
  1         3  
  1         21  
  1         9  
  1         3  
  1         21  
  1         11  
  1         2  
  1         21  
  1         9  
  1         3  
  1         20  
  1         8  
  1         5  
  1         19  
  1         8  
  1         3  
  1         19  
  1         9  
  1         2  
  1         18  
  1         10  
  1         2  
  1         21  
  1         10  
  1         2  
  1         20  
  1         10  
  1         3  
  1         23  
  1         10  
  1         2  
  1         23  
  1         9  
  1         2  
  1         22  
  1         12  
  1         2  
  1         24  
  1         8  
  1         4  
  1         21  
  1         8  
  1         3  
  1         20  
  1         9  
  1         3  
  1         19  
  1         10  
  1         2  
  1         20  
  1         9  
  1         15  
  1         23  
  1         9  
  1         3  
  1         21  
  1         8  
  1         2  
  1         22  
  1         10  
  1         18  
  1         26  
  1         10  
  1         4  
  1         25  
  1         8  
  1         4  
  1         22  
  1         10  
  1         2  
  1         21  
  1         10  
  1         2  
  1         20  
  1         11  
  1         2  
  1         37  
  1         8  
  1         3  
  1         21  
  1         9  
  1         3  
  1         19  
  1         10  
  1         3  
  1         20  
  1         9  
  1         3  
  1         19  
  1         9  
  1         2  
  1         20  
  1         9  
  1         3  
  1         19  
  1         28  
  1         3  
  1         21  
  1         11  
  1         4  
  1         22  
  1         9  
  1         3  
  1         22  
  1         10  
  1         3  
  1         20  
  1         11  
  1         4  
  1         22  
  1         9  
  1         4  
  1         21  
  1         9  
  1         3  
  1         21  
  1         10  
  1         2  
  1         20  
  1         12  
  1         2  
  1         24  
  1         10  
  1         3  
  1         41  
  1         9  
  1         2  
  1         22  
  1         8  
  1         3  
  1         21  
  1         9  
  1         3  
  1         20  
  1         9  
  1         2  
  1         22  
  1         10  
  1         4  
  1         24  
  1         10  
  1         4  
  1         22  
  1         10  
  1         3  
  1         21  
  1         8  
  1         2  
  1         18  
  1         8  
  1         2  
  1         19  
  1         9  
  1         3  
  1         20  
  1         9  
  1         3  
  1         52  
  1         10  
  1         3  
  1         35  
  1         9  
  1         3  
  1         19  
  1         9  
  1         3  
  1         21  
  1         9  
  1         2  
  1         20  
  1         7  
  1         1  
  1         15  
  1         6  
  1         2  
  1         15  
  1         7  
  1         2  
  1         11  
  1         8  
  1         2  
  1         14  
  1         4  
  1         3  
  1         10  
  1         4  
  1         2  
  1         33  
  1         6  
  1         1  
  1         10  
  1         5  
  1         1  
  1         9  
  1         6  
  1         2  
  1         10  
  1         4  
  1         2  
  1         9  
  1         4  
  1         2  
  1         9  
  1         5  
  1         3  
  1         13  
  1         7  
  1         2  
  1         16  
  1         6  
  1         2  
  1         13  
  1         4  
  1         2  
  1         10  
  1         6  
  1         1  
  1         12  
  1         4  
  1         20  
  1         12  
  1         4  
  1         2  
  1         9  
  1         5  
  1         1  
  1         9  
  1         4  
  1         2  
  1         8  
  1         4  
  1         1  
  1         9  
  1         4  
  1         1  
  1         9  
  1         5  
  1         1  
  1         8  
  1         4  
  1         2  
  1         8  
  1         7  
  1         2  
  1         14  
  1         6  
  1         1  
  1         16  
  1         4  
  1         2  
  1         12  
  1         5  
  1         2  
  1         10  
  1         4  
  1         2  
  1         11  
  1         7  
  1         2  
  1         36  
  1         4  
  1         2  
  1         10  
  1         4  
  1         1  
  1         9  
  1         4  
  1         2  
  1         9  
  1         8  
  1         3  
  1         17  
  1         5  
  1         2  
  1         10  
  1         4  
  1         2  
  1         8  
  1         6  
  1         1  
  1         13  
  1         5  
  1         2  
  1         13  
  1         8  
  1         3  
  1         20  
  1         5  
  1         2  
  1         11  
  1         5  
  1         1  
  1         10  
  1         4  
  1         2  
  1         10  
  1         10  
  1         3  
  1         15  
  1         5  
  1         2  
  1         8  
  1         4  
  1         1  
  1         9  
  1         5  
  1         1  
  1         9  
  1         4  
  1         2  
  1         10  
  1         5  
  1         2  
  1         7  
  1         5  
  1         2  
  1         14  
  1         5  
  1         2  
  1         13  
  1         5  
  1         2  
  1         11  
  1         4  
  1         2  
  1         10  
  1         5  
  1         1  
  1         9  
  1         4  
  1         1  
  1         9  
  1         4  
  1         2  
  1         28  
  1         4  
  1         1  
  1         8  
  1         4  
  1         1  
  1         9  
  1         4  
  1         2  
  1         9  
  1         4  
  1         1  
  1         10  
  1         4  
  1         9  
  1         9  
297 3172         8655 $error = $@;
298             }
299 3508         6423 $@ = $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 3508 100       16077 return unless $failed;
303 61   50     629 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 138     145   532 my ($array_ref, $prefix, $ddp) = @_;
312              
313 138         297 my $max_function = $prefix . '_max';
314 138         591 my $preserve_function = $prefix . '_preserve';
315 136         560 my $overflow_function = $prefix . '_overflow';
316 136         641 my $max = $ddp->$max_function;
317 136         768 my $preserve = $ddp->$preserve_function;
318              
319 136 100 100     820 return (0 .. $#{$array_ref}) if !$max || @$array_ref <= $max;
  124         539  
320              
321 32         388 my $skip_message = $ddp->maybe_colorize($ddp->$overflow_function, 'overflow');
322 30 100 100     321 if ($preserve eq 'begin' || $preserve eq 'end') {
    100          
    100          
323 23         66 my $n_elements = @$array_ref - $max;
324 23         340 $skip_message =~ s/__SKIPPED__/$n_elements/g;
325             return $preserve eq 'begin'
326             ? ((0 .. ($max - 1)), \$skip_message)
327 24 100       234 : (\$skip_message, ($n_elements .. $#{$array_ref}))
  19         50  
328             ;
329             }
330             elsif ($preserve eq 'extremes') {
331 19         309 my $half_max = int($max / 2);
332 19         285 my $last_index_of_chunk_one = $half_max - 1;
333 18         56 my $n_elements = @$array_ref - $max;
334              
335 18         427 my $first_index_of_chunk_two = @$array_ref - ($max - $half_max);
336 19         249 $skip_message =~ s/__SKIPPED__/$n_elements/g;
337             return (
338             (0 .. $last_index_of_chunk_one),
339             \$skip_message,
340 18         41 ($first_index_of_chunk_two .. $#{$array_ref})
  18         273  
341             );
342             }
343             elsif ($preserve eq 'middle') {
344 19         122 my $array_middle = int($#{$array_ref} / 2);
  19         194  
345 19         294 my $first_index_to_show = $array_middle - int($max / 2);
346 19         122 my $last_index_to_show = $first_index_to_show + $max - 1;
347 19         45 my ($message_begin, $message_end) = ($skip_message, $skip_message);
348 19         297 $message_begin =~ s/__SKIPPED__/$first_index_to_show/gse;
  19         136  
349 19         46 my $items_left = $#{$array_ref} - $last_index_to_show;
  19         299  
350 19         144 $message_end =~ s/__SKIPPED__/$items_left/gs;
351             return (
352 19         92 \$message_begin,
353             $first_index_to_show .. $last_index_to_show,
354             \$message_end
355             );
356             }
357             else { # $preserve eq 'none'
358 19         326 my $n_elements = scalar(@$array_ref);
359 19         142 $skip_message =~ s/__SKIPPED__/$n_elements/g;
360 19         56 return (\$skip_message);
361             }
362             }
363              
364             # helpers below strongly inspired by the excellent Package::Stash:
365             sub _linear_ISA_for {
366 172     184   634 my ($class, $ddp) = @_;
367 172 100       514 _initialize_mro($ddp) unless $mro_initialized;
368 172         269 my $isa;
369 172 50       663 if ($mro_initialized > 0) {
370 161         743 $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 6         24 $isa = [ $class, _get_superclasses_for($class) ];
376             }
377 161 100       683 return [@$isa, ($ddp->class->universal ? 'UNIVERSAL' : ())];
378             }
379              
380             sub _initialize_mro {
381 18     41   78 my ($ddp) = @_;
382             my $error = _tryme(sub {
383 18 50   41   160 if ($] < 5.009_005) { require MRO::Compat }
  6         71  
384 18         180 else { require mro }
385 18         204 1;
386 18         118 });
387 17 0 33     134 if ($error && index($error, 'in @INC') != -1 && $mro_initialized == 0) {
      33        
388 5 0       10 _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 17 50       152 $mro_initialized = $error ? -1 : 1;
395             }
396              
397             sub _get_namespace {
398 122     146   293 my ($class_name) = @_;
399 122         178 my $namespace;
400             {
401 83     83   747 no strict 'refs';
  83         169  
  83         11380  
  122         312  
402 122         210 $namespace = \%{ $class_name . '::' }
  122         435  
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 122 50       452 Scalar::Util::weaken($namespace) if $] >= 5.010;
407              
408 122         363 return $namespace;
409             }
410              
411             sub _get_superclasses_for {
412 46     69   95 my ($class_name) = @_;
413 46         198 my $namespace = _get_namespace($class_name);
414 46         199 my $res = _get_symbol($class_name, $namespace, 'ISA', 'ARRAY');
415 46 100       86 return @{ $res || [] };
  46         321  
416             }
417              
418             sub _get_symbol {
419 307     329   595 my ($class_name, $namespace, $symbol_name, $symbol_kind) = @_;
420              
421 307 100       617 if (exists $namespace->{$symbol_name}) {
422 292         521 my $entry_ref = \$namespace->{$symbol_name};
423 292 50       577 if (ref($entry_ref) eq 'GLOB') {
424 292         400 return *{$entry_ref}{$symbol_kind};
  292         937  
425             }
426             else {
427 5 0       33 if ($symbol_kind eq 'CODE') {
428 83     83   678 no strict 'refs';
  83         198  
  83         5117  
429 5         12 return \&{ $class_name . '::' . $symbol_name };
  5         85  
430             }
431             }
432             }
433 20         62 return;
434             }
435              
436             1;