| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Data::Printer; |
|
2
|
8
|
|
|
8
|
|
5311
|
use strict; |
|
|
8
|
|
|
|
|
15
|
|
|
|
8
|
|
|
|
|
318
|
|
|
3
|
8
|
|
|
8
|
|
65
|
use warnings; |
|
|
8
|
|
|
|
|
16
|
|
|
|
8
|
|
|
|
|
408
|
|
|
4
|
8
|
|
|
8
|
|
4991
|
use Data::Printer::Object; |
|
|
8
|
|
|
|
|
30
|
|
|
|
8
|
|
|
|
|
327
|
|
|
5
|
8
|
|
|
8
|
|
52
|
use Data::Printer::Common; |
|
|
8
|
|
|
|
|
16
|
|
|
|
8
|
|
|
|
|
153
|
|
|
6
|
8
|
|
|
8
|
|
34
|
use Data::Printer::Config; |
|
|
8
|
|
|
|
|
12
|
|
|
|
8
|
|
|
|
|
1726
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '1.002001'; |
|
9
|
|
|
|
|
|
|
$VERSION = eval $VERSION; |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
my $rc_arguments; |
|
12
|
|
|
|
|
|
|
my %arguments_for; |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub import { |
|
15
|
10
|
|
|
10
|
|
118
|
my $class = shift; |
|
16
|
|
|
|
|
|
|
|
|
17
|
10
|
|
|
|
|
31
|
_initialize(); |
|
18
|
|
|
|
|
|
|
|
|
19
|
10
|
|
|
|
|
16
|
my $args; |
|
20
|
10
|
100
|
|
|
|
31
|
if (@_ > 0) { |
|
21
|
8
|
50
|
|
|
|
49
|
$args = @_ == 1 ? shift : {@_}; |
|
22
|
8
|
50
|
|
|
|
28
|
Data::Printer::Common::_warn( |
|
23
|
|
|
|
|
|
|
undef, |
|
24
|
|
|
|
|
|
|
'Data::Printer can receive either a hash or a hash reference' |
|
25
|
|
|
|
|
|
|
) unless ref $args eq 'HASH'; |
|
26
|
|
|
|
|
|
|
$args = Data::Printer::Config::_expand_profile($args) |
|
27
|
8
|
50
|
|
|
|
23
|
if exists $args->{profile}; |
|
28
|
|
|
|
|
|
|
} |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# every time you load it, we override the version from *your* caller |
|
31
|
10
|
|
|
|
|
24
|
my $caller = caller; |
|
32
|
10
|
|
|
|
|
25
|
$arguments_for{$caller} = $args; |
|
33
|
|
|
|
|
|
|
|
|
34
|
10
|
|
|
|
|
33
|
my $use_prototypes = _find_option('use_prototypes', $args, $caller, 1); |
|
35
|
10
|
100
|
|
|
|
32
|
my $exported = ($use_prototypes ? \&p : \&_p_without_prototypes); |
|
36
|
|
|
|
|
|
|
|
|
37
|
10
|
|
|
|
|
22
|
my $imported = _find_option('alias', $args, $caller, 'p'); |
|
38
|
|
|
|
|
|
|
|
|
39
|
8
|
|
|
8
|
|
77
|
{ no strict 'refs'; |
|
|
8
|
|
|
|
|
21
|
|
|
|
8
|
|
|
|
|
1183
|
|
|
|
10
|
|
|
|
|
18
|
|
|
40
|
10
|
|
|
|
|
46
|
*{"$caller\::$imported"} = $exported; |
|
|
10
|
|
|
|
|
81
|
|
|
41
|
10
|
|
|
|
|
22
|
*{"$caller\::np"} = \&np; |
|
|
10
|
|
|
|
|
11677
|
|
|
42
|
|
|
|
|
|
|
} |
|
43
|
|
|
|
|
|
|
} |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub _initialize { |
|
46
|
|
|
|
|
|
|
# potential race but worst case is we read it twice :) |
|
47
|
8
|
|
|
8
|
|
141
|
{ no warnings 'redefine'; *_initialize = sub {} } |
|
|
8
|
|
|
63
|
|
14
|
|
|
|
8
|
|
|
|
|
1703
|
|
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
my $rc_filename = Data::Printer::Config::_get_first_rc_file_available(); |
|
50
|
|
|
|
|
|
|
$rc_arguments = Data::Printer::Config::load_rc_file($rc_filename); |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
if ( |
|
53
|
|
|
|
|
|
|
exists $rc_arguments->{'_'}{live_update} |
|
54
|
|
|
|
|
|
|
&& defined $rc_arguments->{'_'}{live_update} |
|
55
|
|
|
|
|
|
|
&& $rc_arguments->{'_'}{live_update} =~ /\A\d+\z/ |
|
56
|
|
|
|
|
|
|
&& $rc_arguments->{'_'}{live_update} > 0) { |
|
57
|
|
|
|
|
|
|
my $now = time; |
|
58
|
|
|
|
|
|
|
my $last_mod = (stat $rc_filename)[9]; |
|
59
|
|
|
|
|
|
|
{ |
|
60
|
8
|
|
|
8
|
|
49
|
no warnings 'redefine'; |
|
|
8
|
|
|
|
|
17
|
|
|
|
8
|
|
|
|
|
12732
|
|
|
61
|
|
|
|
|
|
|
*_initialize = sub { |
|
62
|
|
|
|
|
|
|
if (time - $now > $rc_arguments->{'_'}{live_update}) { |
|
63
|
|
|
|
|
|
|
my $new_last_mod = (stat $rc_filename)[9]; |
|
64
|
|
|
|
|
|
|
if (defined $new_last_mod && $new_last_mod > $last_mod) { |
|
65
|
|
|
|
|
|
|
$now = time; |
|
66
|
|
|
|
|
|
|
$last_mod = $new_last_mod; |
|
67
|
|
|
|
|
|
|
$rc_arguments = Data::Printer::Config::load_rc_file($rc_filename); |
|
68
|
|
|
|
|
|
|
if (!exists $rc_arguments->{'_'}{live_update} || !$rc_arguments->{'_'}{live_update}) { |
|
69
|
|
|
|
|
|
|
*_initialize = sub {}; |
|
70
|
|
|
|
|
|
|
} |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
} |
|
73
|
|
|
|
|
|
|
}; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub np (\[@$%&];%) { |
|
79
|
13
|
|
|
13
|
1
|
11684
|
my (undef, %properties) = @_; |
|
80
|
|
|
|
|
|
|
|
|
81
|
13
|
|
|
|
|
44
|
_initialize(); |
|
82
|
|
|
|
|
|
|
|
|
83
|
13
|
|
|
|
|
28
|
my $caller = caller; |
|
84
|
13
|
|
|
|
|
40
|
my $args_to_use = _fetch_args_with($caller, \%properties); |
|
85
|
13
|
50
|
|
|
|
69
|
return '' if $args_to_use->{quiet}; |
|
86
|
13
|
|
|
|
|
56
|
my $printer = Data::Printer::Object->new($args_to_use); |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# force color level 0 on 'auto' colors: |
|
89
|
13
|
50
|
|
|
|
87
|
if ($printer->colored eq 'auto') { |
|
90
|
0
|
|
|
|
|
0
|
$printer->{_output_color_level} = 0; |
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
|
|
93
|
13
|
|
|
|
|
46
|
my $ref = ref $_[0]; |
|
94
|
13
|
100
|
100
|
|
|
92
|
if ($ref eq 'ARRAY' || $ref eq 'HASH' || ($ref eq 'REF' && ref ${$_[0]} eq 'REF')) { |
|
|
10
|
|
100
|
|
|
53
|
|
|
|
|
|
100
|
|
|
|
|
|
95
|
3
|
|
|
|
|
6
|
$printer->{_refcount_base}++; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
13
|
|
|
|
|
53
|
my $output = $printer->parse($_[0]); |
|
98
|
13
|
50
|
|
|
|
46
|
if ($printer->caller_message_position eq 'after') { |
|
99
|
0
|
|
|
|
|
0
|
$output .= $printer->_write_label; |
|
100
|
|
|
|
|
|
|
} |
|
101
|
|
|
|
|
|
|
else { |
|
102
|
13
|
|
|
|
|
37
|
$output = $printer->_write_label . $output; |
|
103
|
|
|
|
|
|
|
} |
|
104
|
13
|
|
|
|
|
462
|
return $output; |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub p (\[@$%&];%) { |
|
109
|
44
|
|
|
44
|
1
|
1180705
|
my (undef, %properties) = @_; |
|
110
|
|
|
|
|
|
|
|
|
111
|
44
|
|
|
|
|
191
|
_initialize(); |
|
112
|
|
|
|
|
|
|
|
|
113
|
44
|
|
|
|
|
123
|
my $caller = caller; |
|
114
|
44
|
|
|
|
|
152
|
my $args_to_use = _fetch_args_with($caller, \%properties); |
|
115
|
44
|
|
|
|
|
110
|
my $want_value = defined wantarray; |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# return as quickly as possible under 'quiet'. |
|
118
|
44
|
50
|
|
|
|
159
|
if ($args_to_use->{quiet}) { |
|
119
|
|
|
|
|
|
|
# we avoid creating a Data::Printer::Object instance |
|
120
|
|
|
|
|
|
|
# to speed things up, since we don't do anything under 'quiet'. |
|
121
|
0
|
|
|
|
|
0
|
my $return_type = Data::Printer::Common::_fetch_anyof( |
|
122
|
|
|
|
|
|
|
$args_to_use, 'return_value', 'pass', [qw(pass dump void)] |
|
123
|
|
|
|
|
|
|
); |
|
124
|
0
|
|
|
|
|
0
|
return _handle_output(undef, undef, $want_value, $_[0], $return_type, 1); |
|
125
|
|
|
|
|
|
|
} |
|
126
|
|
|
|
|
|
|
|
|
127
|
44
|
|
|
|
|
330
|
my $printer = Data::Printer::Object->new($args_to_use); |
|
128
|
|
|
|
|
|
|
|
|
129
|
44
|
0
|
33
|
|
|
170
|
if ($printer->colored eq 'auto' && $printer->return_value eq 'dump' && $want_value) { |
|
|
|
|
33
|
|
|
|
|
|
130
|
0
|
|
|
|
|
0
|
$printer->{_output_color_level} = 0; |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
|
|
133
|
44
|
|
|
|
|
140
|
my $ref = ref $_[0]; |
|
134
|
44
|
100
|
100
|
|
|
371
|
if ($ref eq 'ARRAY' || $ref eq 'HASH' || ($ref eq 'REF' && ref ${$_[0]} eq 'REF')) { |
|
|
17
|
|
100
|
|
|
87
|
|
|
|
|
|
100
|
|
|
|
|
|
135
|
7
|
|
|
|
|
51
|
$printer->{_refcount_base}++; |
|
136
|
|
|
|
|
|
|
} |
|
137
|
44
|
|
|
|
|
181
|
my $output = $printer->parse($_[0]); |
|
138
|
44
|
100
|
|
|
|
141
|
if ($printer->caller_message_position eq 'after') { |
|
139
|
1
|
|
|
|
|
4
|
$output .= $printer->_write_label; |
|
140
|
|
|
|
|
|
|
} |
|
141
|
|
|
|
|
|
|
else { |
|
142
|
43
|
|
|
|
|
129
|
$output = $printer->_write_label . $output; |
|
143
|
|
|
|
|
|
|
} |
|
144
|
|
|
|
|
|
|
|
|
145
|
44
|
|
|
|
|
754
|
return _handle_output($output, $printer->{output_handle}, $want_value, $_[0], $printer->return_value, undef); |
|
146
|
|
|
|
|
|
|
} |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# This is a p() clone without prototypes. Just like regular Data::Dumper, |
|
149
|
|
|
|
|
|
|
# this version expects a reference as its first argument. We make a single |
|
150
|
|
|
|
|
|
|
# exception for when we only get one argument, in which case we ref it |
|
151
|
|
|
|
|
|
|
# for the user and keep going. |
|
152
|
|
|
|
|
|
|
sub _p_without_prototypes { |
|
153
|
4
|
|
|
4
|
|
271501
|
my (undef, %properties) = @_; |
|
154
|
|
|
|
|
|
|
|
|
155
|
4
|
|
|
|
|
11
|
my $item; |
|
156
|
4
|
100
|
66
|
|
|
28
|
if (!ref $_[0] && @_ == 1) { |
|
157
|
1
|
|
|
|
|
3
|
my $item_value = $_[0]; |
|
158
|
1
|
|
|
|
|
3
|
$item = \$item_value; |
|
159
|
|
|
|
|
|
|
} |
|
160
|
|
|
|
|
|
|
|
|
161
|
4
|
|
|
|
|
16
|
_initialize(); |
|
162
|
|
|
|
|
|
|
|
|
163
|
4
|
|
|
|
|
11
|
my $caller = caller; |
|
164
|
4
|
|
|
|
|
17
|
my $args_to_use = _fetch_args_with($caller, \%properties); |
|
165
|
4
|
|
|
|
|
10
|
my $want_value = defined wantarray; |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
# return as quickly as possible under 'quiet'. |
|
168
|
4
|
50
|
|
|
|
14
|
if ($args_to_use->{quiet}) { |
|
169
|
|
|
|
|
|
|
# we avoid creating a Data::Printer::Object instance |
|
170
|
|
|
|
|
|
|
# to speed things up, since we don't do anything under 'quiet'. |
|
171
|
0
|
|
|
|
|
0
|
my $return_type = Data::Printer::Common::_fetch_anyof( |
|
172
|
|
|
|
|
|
|
$args_to_use, 'return_value', 'pass', [qw(pass dump void)] |
|
173
|
|
|
|
|
|
|
); |
|
174
|
0
|
|
|
|
|
0
|
return _handle_output(undef, undef, $want_value, $_[0], $return_type, 1); |
|
175
|
|
|
|
|
|
|
} |
|
176
|
|
|
|
|
|
|
|
|
177
|
4
|
|
|
|
|
35
|
my $printer = Data::Printer::Object->new($args_to_use); |
|
178
|
|
|
|
|
|
|
|
|
179
|
4
|
0
|
33
|
|
|
16
|
if ($printer->colored eq 'auto' && $printer->return_value eq 'dump' && $want_value) { |
|
|
|
|
33
|
|
|
|
|
|
180
|
0
|
|
|
|
|
0
|
$printer->{_output_color_level} = 0; |
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
|
|
183
|
4
|
100
|
|
|
|
22
|
my $ref = ref( defined $item ? $item : $_[0] ); |
|
184
|
4
|
0
|
100
|
|
|
27
|
if ($ref eq 'ARRAY' || $ref eq 'HASH' || ($ref eq 'REF' |
|
|
|
100
|
33
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
185
|
0
|
|
|
|
|
0
|
&& ref(defined $item ? $item : ${$_[0]}) eq 'REF')) { |
|
186
|
2
|
|
|
|
|
6
|
$printer->{_refcount_base}++; |
|
187
|
|
|
|
|
|
|
} |
|
188
|
4
|
100
|
|
|
|
20
|
my $output = $printer->parse((defined $item ? $item : $_[0])); |
|
189
|
4
|
50
|
|
|
|
11
|
if ($printer->caller_message_position eq 'after') { |
|
190
|
0
|
|
|
|
|
0
|
$output .= $printer->_write_label; |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
else { |
|
193
|
4
|
|
|
|
|
14
|
$output = $printer->_write_label . $output; |
|
194
|
|
|
|
|
|
|
} |
|
195
|
|
|
|
|
|
|
|
|
196
|
4
|
|
|
|
|
21
|
return _handle_output($output, $printer->{output_handle}, $want_value, $_[0], $printer->return_value, undef); |
|
197
|
|
|
|
|
|
|
} |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
sub _handle_output { |
|
201
|
48
|
|
|
48
|
|
266
|
my ($output, $out_handle, $wantarray, $data, $return_type, $quiet) = @_; |
|
202
|
|
|
|
|
|
|
|
|
203
|
48
|
100
|
100
|
|
|
282
|
if ($return_type eq 'pass') { |
|
|
|
100
|
|
|
|
|
|
|
204
|
9
|
50
|
|
|
|
24
|
print { $out_handle } $output . "\n" unless $quiet; |
|
|
9
|
|
|
|
|
566
|
|
|
205
|
9
|
|
|
|
|
93
|
require Scalar::Util; |
|
206
|
9
|
|
|
|
|
19
|
my $ref = Scalar::Util::blessed($data); |
|
207
|
9
|
100
|
|
|
|
77
|
return $data if defined $ref; |
|
208
|
8
|
|
|
|
|
18
|
$ref = Scalar::Util::reftype($data); |
|
209
|
8
|
50
|
|
|
|
38
|
if (!$ref) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
210
|
0
|
|
|
|
|
0
|
return $data; |
|
211
|
|
|
|
|
|
|
} |
|
212
|
|
|
|
|
|
|
elsif ($ref eq 'ARRAY') { |
|
213
|
2
|
|
|
|
|
77
|
return @$data; |
|
214
|
|
|
|
|
|
|
} |
|
215
|
|
|
|
|
|
|
elsif ($ref eq 'HASH') { |
|
216
|
2
|
|
|
|
|
87
|
return %$data; |
|
217
|
|
|
|
|
|
|
} |
|
218
|
12
|
|
|
|
|
28
|
elsif ( grep { $ref eq $_ } qw(REF SCALAR VSTRING) ) { |
|
219
|
4
|
|
|
|
|
132
|
return $$data; |
|
220
|
|
|
|
|
|
|
} |
|
221
|
|
|
|
|
|
|
else { |
|
222
|
0
|
|
|
|
|
0
|
return $data; |
|
223
|
|
|
|
|
|
|
} |
|
224
|
|
|
|
|
|
|
} |
|
225
|
|
|
|
|
|
|
elsif ($return_type eq 'void' || !$wantarray) { |
|
226
|
7
|
50
|
|
|
|
25
|
print { $out_handle} $output . "\n" unless $quiet; |
|
|
7
|
|
|
|
|
385
|
|
|
227
|
7
|
|
|
|
|
447
|
return; |
|
228
|
|
|
|
|
|
|
} |
|
229
|
|
|
|
|
|
|
else { |
|
230
|
32
|
|
|
|
|
1411
|
return $output; |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
} |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
sub _fetch_args_with { |
|
235
|
61
|
|
|
61
|
|
150
|
my ($caller, $run_properties) = @_; |
|
236
|
|
|
|
|
|
|
|
|
237
|
61
|
|
|
|
|
124
|
my $args_to_use = {}; |
|
238
|
61
|
50
|
|
|
|
218
|
if (keys %$rc_arguments) { |
|
239
|
|
|
|
|
|
|
$args_to_use = Data::Printer::Config::_merge_options( |
|
240
|
61
|
|
|
|
|
344
|
$args_to_use, $rc_arguments->{'_'} |
|
241
|
|
|
|
|
|
|
); |
|
242
|
61
|
50
|
|
|
|
228
|
if (exists $rc_arguments->{$caller}) { |
|
243
|
|
|
|
|
|
|
$args_to_use = Data::Printer::Config::_merge_options( |
|
244
|
0
|
|
|
|
|
0
|
$args_to_use, $rc_arguments->{$caller} |
|
245
|
|
|
|
|
|
|
); |
|
246
|
|
|
|
|
|
|
} |
|
247
|
|
|
|
|
|
|
} |
|
248
|
61
|
50
|
|
|
|
200
|
if ($arguments_for{$caller}) { |
|
249
|
|
|
|
|
|
|
$args_to_use = Data::Printer::Config::_merge_options( |
|
250
|
61
|
|
|
|
|
246
|
$args_to_use, $arguments_for{$caller} |
|
251
|
|
|
|
|
|
|
); |
|
252
|
|
|
|
|
|
|
} |
|
253
|
61
|
100
|
|
|
|
192
|
if (keys %$run_properties) { |
|
254
|
|
|
|
|
|
|
$run_properties = Data::Printer::Config::_expand_profile($run_properties) |
|
255
|
15
|
50
|
|
|
|
54
|
if exists $run_properties->{profile}; |
|
256
|
15
|
|
|
|
|
45
|
$args_to_use = Data::Printer::Config::_merge_options( |
|
257
|
|
|
|
|
|
|
$args_to_use, $run_properties |
|
258
|
|
|
|
|
|
|
); |
|
259
|
|
|
|
|
|
|
} |
|
260
|
61
|
|
|
|
|
160
|
return $args_to_use; |
|
261
|
|
|
|
|
|
|
} |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
sub _find_option { |
|
265
|
20
|
|
|
20
|
|
45
|
my ($key, $args, $caller, $default) = @_; |
|
266
|
|
|
|
|
|
|
|
|
267
|
20
|
|
|
|
|
30
|
my $value; |
|
268
|
20
|
100
|
33
|
|
|
83
|
if (exists $args->{$key}) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
269
|
2
|
|
|
|
|
4
|
$value = $args->{$key}; |
|
270
|
|
|
|
|
|
|
} |
|
271
|
|
|
|
|
|
|
elsif ( |
|
272
|
|
|
|
|
|
|
exists $rc_arguments->{$caller} |
|
273
|
|
|
|
|
|
|
&& exists $rc_arguments->{$caller}{$key} |
|
274
|
|
|
|
|
|
|
) { |
|
275
|
0
|
|
|
|
|
0
|
$value = $rc_arguments->{$caller}{$key}; |
|
276
|
|
|
|
|
|
|
} |
|
277
|
|
|
|
|
|
|
elsif (exists $rc_arguments->{'_'}{$key}) { |
|
278
|
0
|
|
|
|
|
0
|
$value = $rc_arguments->{'_'}{$key}; |
|
279
|
|
|
|
|
|
|
} |
|
280
|
|
|
|
|
|
|
else { |
|
281
|
18
|
|
|
|
|
28
|
$value = $default; |
|
282
|
|
|
|
|
|
|
} |
|
283
|
20
|
|
|
|
|
44
|
return $value; |
|
284
|
|
|
|
|
|
|
} |
|
285
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
'Marielle, presente.'; |
|
288
|
|
|
|
|
|
|
__END__ |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=encoding utf8 |
|
291
|
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head1 NAME |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
Data::Printer - colored & full-featured pretty print of Perl data structures and objects |
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
Want to see what's inside a variable in a complete, colored and human-friendly way? |
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
use DDP; # same as 'use Data::Printer' |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
p $some_var; |
|
303
|
|
|
|
|
|
|
p $some_var, as => "This label will be printed too!"; |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
# no need to use '\' before arrays or hashes! |
|
306
|
|
|
|
|
|
|
p @array; |
|
307
|
|
|
|
|
|
|
p %hash; |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
# printing anonymous array references: |
|
310
|
|
|
|
|
|
|
p [ $one, $two, $three ]->@*; # perl 5.24 or later! |
|
311
|
|
|
|
|
|
|
p @{[ $one, $two, $three ]}; # same, older perls |
|
312
|
|
|
|
|
|
|
&p( [ $one, $two, $three ] ); # same, older perls |
|
313
|
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
# printing anonymous hash references: |
|
315
|
|
|
|
|
|
|
p { foo => $foo, bar => $bar }->%*; # perl 5.24 or later! |
|
316
|
|
|
|
|
|
|
p %{{ foo => $foo, bar => $bar }}; # same, older perls |
|
317
|
|
|
|
|
|
|
&p( { foo => $foo, bar => $bar } ); # same, older perls |
|
318
|
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
The snippets above will print the contents of the chosen variables to STDERR |
|
321
|
|
|
|
|
|
|
on your terminal, with colors and a few extra features to help you debug |
|
322
|
|
|
|
|
|
|
your code. |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
If you wish to grab the output and handle it yourself, call C<np()>: |
|
325
|
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
my $dump = np $var; |
|
327
|
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
die "this is what happened: " . np %data; |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
The C<np()> function is the same as C<p()> but will return the string |
|
331
|
|
|
|
|
|
|
containing the dump. By default it has no colors, but you can change that |
|
332
|
|
|
|
|
|
|
easily too. |
|
333
|
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
That's pretty much it :) |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=for html <img alt="samples of Data::Printer output for several kinds of data and objects" src="https://raw.githubusercontent.com/garu/Data-Printer/master/examples/ddp.gif" /> |
|
338
|
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
Data::Printer is L<fully customizable|/Properties Quick Reference>, even |
|
340
|
|
|
|
|
|
|
on a per-module basis! Once you figure out your own preferences, create a |
|
341
|
|
|
|
|
|
|
L<< .dataprinter configuration file|/The .dataprinter configuration file >> |
|
342
|
|
|
|
|
|
|
for yourself (or one for each project) and Data::Printer will automatically |
|
343
|
|
|
|
|
|
|
use it! |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=head1 FEATURES |
|
346
|
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Here's what Data::Printer offers Perl developers, out of the box: |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=over 4 |
|
350
|
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
=item * Variable dumps designed for B<< easy parsing by the human brain >>, |
|
352
|
|
|
|
|
|
|
not a machine. |
|
353
|
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=back |
|
355
|
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=over 4 |
|
357
|
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=item * B<< Highly customizable >>, from indentation size to depth level. |
|
359
|
|
|
|
|
|
|
You can even rename the exported C<p()> function! |
|
360
|
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=back |
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=over 4 |
|
364
|
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=item * B<< Beautiful (and customizable) colors >> to highlight variable dumps |
|
366
|
|
|
|
|
|
|
and make issues stand-out quickly on your console. Comes bundled with |
|
367
|
|
|
|
|
|
|
L<several themes|Data::Printer::Theme> for you to pick that work on light |
|
368
|
|
|
|
|
|
|
and dark terminal backgrounds, and you can create your own as well. |
|
369
|
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=back |
|
371
|
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=over 4 |
|
373
|
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
=item * B<< L<Filters|/Filters> for specific data structures and objects >> to make |
|
375
|
|
|
|
|
|
|
debugging much, much easier. Includes filters for many popular classes |
|
376
|
|
|
|
|
|
|
from CPAN like JSON::*, URI, HTTP::*, LWP, Digest::*, DBI and DBIx::Class. |
|
377
|
|
|
|
|
|
|
printing what really matters to developers debugging code. It also lets you |
|
378
|
|
|
|
|
|
|
create your own custom filters easily. |
|
379
|
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=back |
|
381
|
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
=over 4 |
|
383
|
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=item * Lets you B<< inspect information that's otherwise difficult to find/debug >> |
|
385
|
|
|
|
|
|
|
in Perl 5, like circular references, reference counting (refcount), |
|
386
|
|
|
|
|
|
|
weak/read-only information, overloaded operators, tainted data, ties, |
|
387
|
|
|
|
|
|
|
dual vars, even estimated data size - all to help you spot issues with your |
|
388
|
|
|
|
|
|
|
data like leaks without having to know a lot about internal data structures |
|
389
|
|
|
|
|
|
|
or install hardcore tools like Devel::Peek and Devel::Gladiator. |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
=back |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=over 4 |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=item * B<< Full support for dumping perl 5.38 native classes >>. |
|
396
|
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
=back |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=over 4 |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=item * keep your custom settings on a |
|
402
|
|
|
|
|
|
|
L<< .dataprinter|/The .dataprinter configuration file >> file that allows |
|
403
|
|
|
|
|
|
|
B<< different options per module >> being analyzed! You can have |
|
404
|
|
|
|
|
|
|
B<< one C<.dataprinter> file per project >>, or default to one in your home |
|
405
|
|
|
|
|
|
|
directory. You may also create a custom L<profile|Data::Printer::Profile> class |
|
406
|
|
|
|
|
|
|
with your preferences and filters and upload it to CPAN. |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=back |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
=over 4 |
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
=item * B<< output to many different targets >> like files, variables or open |
|
413
|
|
|
|
|
|
|
handles (defaults to STDERR). You can send your dumps to the screen |
|
414
|
|
|
|
|
|
|
or anywhere else, and customize this setting on a per-project or even |
|
415
|
|
|
|
|
|
|
per-module basis, like print everything from Some::Module to a debug.log |
|
416
|
|
|
|
|
|
|
file with extra info, and everything else to STDERR. |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=back |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=over 4 |
|
421
|
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=item * B<< Easy to learn, easy to master >>. Seriously, the synopsis above |
|
423
|
|
|
|
|
|
|
and the customization section below cover about 90% of all use cases. |
|
424
|
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=back |
|
426
|
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
=over 4 |
|
428
|
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=item * Works on B<< Perl 5.8 and later >>. Because you can't control where |
|
430
|
|
|
|
|
|
|
you debug, we try our best to be compatible with all versions of Perl 5, from |
|
431
|
|
|
|
|
|
|
the oldest available to the bleeding edge. |
|
432
|
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=back |
|
434
|
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=over 4 |
|
436
|
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=item * Best of all? All that with B<< No non-core dependencies >>, |
|
438
|
|
|
|
|
|
|
Zero. Nada. So don't worry about adding extra weight to your project, as |
|
439
|
|
|
|
|
|
|
Data::Printer can be easily added/removed. |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
=back |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
444
|
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
The ever-popular Data::Dumper is a fantastic tool, meant to stringify |
|
446
|
|
|
|
|
|
|
data structures in a way they are suitable for being "eval"'ed back in. |
|
447
|
|
|
|
|
|
|
The thing is, a lot of people keep using it (and similar ones, like |
|
448
|
|
|
|
|
|
|
Data::Dump) to print data structures and objects on screen for inspection |
|
449
|
|
|
|
|
|
|
and debugging, and while you I<can> use those modules for that, it doesn't |
|
450
|
|
|
|
|
|
|
mean you I<should>. |
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
This is where Data::Printer comes in. It is meant to do one thing and one |
|
453
|
|
|
|
|
|
|
thing only: |
|
454
|
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
I<< format Perl variables and objects to be inspected by a human >> |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
If you want to serialize/store/restore Perl data structures, this module |
|
458
|
|
|
|
|
|
|
will NOT help you. Try Storable, Data::Dumper, JSON, or whatever. CPAN is |
|
459
|
|
|
|
|
|
|
full of such solutions! |
|
460
|
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
Whenever you type C<use Data::Printer> or C<use DDP>, we export two functions |
|
462
|
|
|
|
|
|
|
to your namespace: |
|
463
|
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=head2 p() |
|
465
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
This function pretty-prints the contents of whatever variable to STDERR |
|
467
|
|
|
|
|
|
|
(by default), and will use colors by default if your terminal supports it. |
|
468
|
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
p @some_array; |
|
470
|
|
|
|
|
|
|
p %some_hash; |
|
471
|
|
|
|
|
|
|
p $scalar_or_ref; |
|
472
|
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
Note that anonymous structures will only work if you postderef them: |
|
474
|
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
p [$foo, $bar, $baz]->@*; |
|
476
|
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
you may also deref it manually: |
|
478
|
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
p %{{ foo => $foo }}; |
|
480
|
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
or prefix C<p()> with C<&>: |
|
482
|
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
&p( [$foo, $bar, $baz] ); # & (note mandatory parenthesis) |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
You can pass custom options that will work only on that particular call: |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
p @var, as => "some label", colored => 0; |
|
488
|
|
|
|
|
|
|
p %var, show_memsize => 1; |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
By default, C<p()> prints to STDERR and returns the same variable being |
|
491
|
|
|
|
|
|
|
dumped. This lets you quickly wrap variables with C<p()> without worrying |
|
492
|
|
|
|
|
|
|
about changing return values. It means that if you change this: |
|
493
|
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
sub foo { my $x = shift + 13; $x } |
|
495
|
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
to this: |
|
497
|
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
sub foo { my $x = shift + 13; p($x) } |
|
499
|
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
The function will still return C<$x> after printing the contents. This form |
|
501
|
|
|
|
|
|
|
of handling data even allows method chaining, so if you want to inspect what's |
|
502
|
|
|
|
|
|
|
going on in the middle of this: |
|
503
|
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
$object->foo->bar->baz; |
|
505
|
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
You can just add C<DDP::p> anywhere: |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
$object->foo->DDP::p->bar->baz; # what happens to $object after ->foo? |
|
509
|
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
Check out the L<customization quick reference|/Properties Quick Reference> |
|
511
|
|
|
|
|
|
|
section below for all available options, including changing the return type, |
|
512
|
|
|
|
|
|
|
output target and a lot more. |
|
513
|
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
=head2 np() |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
The C<np()> function behaves exactly like C<p()> except it always returns |
|
517
|
|
|
|
|
|
|
the string containing the dump (thus ignoring any setting regarding dump |
|
518
|
|
|
|
|
|
|
mode or destination), and contains no colors by default. In fact, the only |
|
519
|
|
|
|
|
|
|
way to force a colored C<np()> is to pass C<< colored => 1 >> as an argument |
|
520
|
|
|
|
|
|
|
to each call. It is meant to provide an easy way to fetch the dump and send |
|
521
|
|
|
|
|
|
|
it to some unsupported target, or appended to some other text (like part of |
|
522
|
|
|
|
|
|
|
a log message). |
|
523
|
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
=head1 CUSTOMIZATION |
|
526
|
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
There are 3 possible ways to customize Data::Printer: |
|
528
|
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
1. B<[RECOMMENDED]> Creating a C<.dataprinter> file either on your home |
|
530
|
|
|
|
|
|
|
directory or your project's base directory, or both, or wherever you set |
|
531
|
|
|
|
|
|
|
the C<DATAPRINTERRC> environment variable to. |
|
532
|
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
2. Setting custom properties on module load. This will override any |
|
534
|
|
|
|
|
|
|
setting from your config file on the namespace (package/module) it was called: |
|
535
|
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
use DDP max_depth => 2, deparse => 1; |
|
537
|
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
3. Setting custom properties on the actual call to C<p()> or C<np()>. This |
|
539
|
|
|
|
|
|
|
overrides all other settings: |
|
540
|
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
p $var, show_tainted => 1, indent => 2; |
|
542
|
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=head2 The .dataprinter configuration file |
|
545
|
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
The most powerful way to customize Data::Printer is to have a C<.dataprinter> |
|
547
|
|
|
|
|
|
|
file in your home directory or your project's root directory. The format |
|
548
|
|
|
|
|
|
|
is super simple and can be understood in the example below: |
|
549
|
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
# global settings (note that only full line comments are accepted) |
|
551
|
|
|
|
|
|
|
max_depth = 1 |
|
552
|
|
|
|
|
|
|
theme = Monokai |
|
553
|
|
|
|
|
|
|
class.stringify = 0 |
|
554
|
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
# use quotes if you want spaces to be significant: |
|
556
|
|
|
|
|
|
|
hash_separator = " => " |
|
557
|
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
# You can set rules that apply only to a specific |
|
559
|
|
|
|
|
|
|
# caller module (in this case, MyApp::Some::Module): |
|
560
|
|
|
|
|
|
|
[MyApp::Some::Module] |
|
561
|
|
|
|
|
|
|
max_depth = 2 |
|
562
|
|
|
|
|
|
|
class.expand = 0 |
|
563
|
|
|
|
|
|
|
escape_chars = nonlatin1 |
|
564
|
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
[MyApp::Other::Module] |
|
566
|
|
|
|
|
|
|
multiline = 0 |
|
567
|
|
|
|
|
|
|
output = /var/log/myapp/debug.data |
|
568
|
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
# use 'quiet' to silence all output from p() and np() |
|
570
|
|
|
|
|
|
|
# called from the specified package. |
|
571
|
|
|
|
|
|
|
[MyApp::Yet::Another] |
|
572
|
|
|
|
|
|
|
quiet = 1 |
|
573
|
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
Note that if you set custom properties as arguments to C<p()> or C<np()>, you |
|
575
|
|
|
|
|
|
|
should group suboptions as a hashref. So while the C<.dataprinter> file has |
|
576
|
|
|
|
|
|
|
"C<< class.expand = 0 >>" and "C<< class.inherited = none >>", the equivalent |
|
577
|
|
|
|
|
|
|
code is "C<< class => { expand => 0, inherited => 'none' } >>". |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=head3 live updating your .dataprinter without restarts |
|
580
|
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
Data::Printer 1.1 introduces a new 'live_update' flag that can be set to a |
|
582
|
|
|
|
|
|
|
positive integer to enable live updates. When this mode is on, Data::Printer |
|
583
|
|
|
|
|
|
|
will check if the C<.dataprinter> file has been updated and, if so, it will |
|
584
|
|
|
|
|
|
|
reload it. This way you can toggle features on and off and control output |
|
585
|
|
|
|
|
|
|
verbosity directly from your C<.dataprinter> file without needing to change |
|
586
|
|
|
|
|
|
|
or restart running code. |
|
587
|
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
=head2 Properties Quick Reference |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
Below are (almost) all available properties and their (hopefully sane) |
|
591
|
|
|
|
|
|
|
default values. See L<Data::Printer::Object> for further information on |
|
592
|
|
|
|
|
|
|
each of them: |
|
593
|
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
# scalar options |
|
595
|
|
|
|
|
|
|
show_tainted = 1 |
|
596
|
|
|
|
|
|
|
show_unicode = 1 |
|
597
|
|
|
|
|
|
|
show_lvalue = 1 |
|
598
|
|
|
|
|
|
|
print_escapes = 0 |
|
599
|
|
|
|
|
|
|
scalar_quotes = " |
|
600
|
|
|
|
|
|
|
escape_chars = none |
|
601
|
|
|
|
|
|
|
string_max = 4096 |
|
602
|
|
|
|
|
|
|
string_preserve = begin |
|
603
|
|
|
|
|
|
|
string_overflow = '(...skipping __SKIPPED__ chars...)' |
|
604
|
|
|
|
|
|
|
unicode_charnames = 0 |
|
605
|
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
# array options |
|
607
|
|
|
|
|
|
|
array_max = 100 |
|
608
|
|
|
|
|
|
|
array_preserve = begin |
|
609
|
|
|
|
|
|
|
array_overflow = '(...skipping __SKIPPED__ items...)' |
|
610
|
|
|
|
|
|
|
index = 1 |
|
611
|
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
# hash options |
|
613
|
|
|
|
|
|
|
hash_max = 100 |
|
614
|
|
|
|
|
|
|
hash_preserve = begin |
|
615
|
|
|
|
|
|
|
hash_overflow = '(...skipping __SKIPPED__ keys...)' |
|
616
|
|
|
|
|
|
|
hash_separator = ' ' |
|
617
|
|
|
|
|
|
|
align_hash = 1 |
|
618
|
|
|
|
|
|
|
sort_keys = 1 |
|
619
|
|
|
|
|
|
|
quote_keys = auto |
|
620
|
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
# general options |
|
622
|
|
|
|
|
|
|
name = var |
|
623
|
|
|
|
|
|
|
return_value = pass |
|
624
|
|
|
|
|
|
|
output = stderr |
|
625
|
|
|
|
|
|
|
use_prototypes = 1 |
|
626
|
|
|
|
|
|
|
indent = 4 |
|
627
|
|
|
|
|
|
|
show_readonly = 1 |
|
628
|
|
|
|
|
|
|
show_tied = 1 |
|
629
|
|
|
|
|
|
|
show_dualvar = lax |
|
630
|
|
|
|
|
|
|
show_weak = 1 |
|
631
|
|
|
|
|
|
|
show_refcount = 0 |
|
632
|
|
|
|
|
|
|
show_memsize = 0 |
|
633
|
|
|
|
|
|
|
memsize_unit = auto |
|
634
|
|
|
|
|
|
|
separator = , |
|
635
|
|
|
|
|
|
|
end_separator = 0 |
|
636
|
|
|
|
|
|
|
caller_info = 0 |
|
637
|
|
|
|
|
|
|
caller_message = 'Printing in line __LINE__ of __FILENAME__' |
|
638
|
|
|
|
|
|
|
max_depth = 0 |
|
639
|
|
|
|
|
|
|
deparse = 0 |
|
640
|
|
|
|
|
|
|
alias = p |
|
641
|
|
|
|
|
|
|
warnings = 1 |
|
642
|
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
# colorization (see Colors & Themes below) |
|
644
|
|
|
|
|
|
|
colored = auto |
|
645
|
|
|
|
|
|
|
theme = Material |
|
646
|
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
# object output |
|
648
|
|
|
|
|
|
|
class_method = _data_printer |
|
649
|
|
|
|
|
|
|
class.parents = 1 |
|
650
|
|
|
|
|
|
|
class.linear_isa = auto |
|
651
|
|
|
|
|
|
|
class.universal = 1 |
|
652
|
|
|
|
|
|
|
class.expand = 1 |
|
653
|
|
|
|
|
|
|
class.stringify = 1 |
|
654
|
|
|
|
|
|
|
class.show_reftype = 0 |
|
655
|
|
|
|
|
|
|
class.show_overloads = 1 |
|
656
|
|
|
|
|
|
|
class.show_methods = all |
|
657
|
|
|
|
|
|
|
class.sort_methods = 1 |
|
658
|
|
|
|
|
|
|
class.inherited = none |
|
659
|
|
|
|
|
|
|
class.format_inheritance = string |
|
660
|
|
|
|
|
|
|
class.parent_filters = 1 |
|
661
|
|
|
|
|
|
|
class.internals = 1 |
|
662
|
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
=head3 Settings' shortcuts |
|
665
|
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=over 4 |
|
667
|
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
=item * B<as> - prints a string before the dump. So: |
|
669
|
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
p $some_var, as => 'here!'; |
|
671
|
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
is a shortcut to: |
|
673
|
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
p $some_var, caller_info => 1, caller_message => 'here!'; |
|
675
|
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
=item * B<multiline> - lets you create shorter dumps. By setting it to 0, |
|
677
|
|
|
|
|
|
|
we use a single space as linebreak and disable the array index. Setting it |
|
678
|
|
|
|
|
|
|
to 1 (the default) goes back to using "\n" as linebreak and restore whatever |
|
679
|
|
|
|
|
|
|
array index you had originally. |
|
680
|
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
=item * B<fulldump> - when set to 1, disables all max string/hash/array |
|
682
|
|
|
|
|
|
|
values. Use this to generate complete (full) dumps of all your content, |
|
683
|
|
|
|
|
|
|
which is trimmed by default. |
|
684
|
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
=item * B<quiet> - when set to 1, disables all data parsing and returns as |
|
686
|
|
|
|
|
|
|
quickly as possible. Use this to disable all output from C<p()> and C<np()> |
|
687
|
|
|
|
|
|
|
inside a particular package, either from the 'use' call or from .dataprinter. |
|
688
|
|
|
|
|
|
|
(introduced in version 1.1) |
|
689
|
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
=back |
|
691
|
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
=head2 Colors & Themes |
|
694
|
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
Data::Printer lets you set custom colors for pretty much every part of the |
|
696
|
|
|
|
|
|
|
content being printed. For example, if you want numbers to be shown in |
|
697
|
|
|
|
|
|
|
bright green, just put C<< colors.number = #00ff00 >> on your configuration |
|
698
|
|
|
|
|
|
|
file. |
|
699
|
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
See L<Data::Printer::Theme> for the full list of labels, ways to represent |
|
701
|
|
|
|
|
|
|
and customize colors, and even how to group them in your own custom theme. |
|
702
|
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
The colorization is set by the C<colored> property. It can be set to 0 |
|
704
|
|
|
|
|
|
|
(never colorize), 1 (always colorize) or 'auto' (the default), which will |
|
705
|
|
|
|
|
|
|
colorize C<p()> only when there is no C<ANSI_COLORS_DISABLED> environment |
|
706
|
|
|
|
|
|
|
variable, the output is going to the terminal (STDOUT or STDERR) and your |
|
707
|
|
|
|
|
|
|
terminal actually supports colors. |
|
708
|
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
=head2 Profiles |
|
711
|
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
You may bundle your settings and filters into a profile module. |
|
713
|
|
|
|
|
|
|
It works like a configuration file but gives you the power and flexibility |
|
714
|
|
|
|
|
|
|
to use Perl code to find out what to print and how to print. It also lets |
|
715
|
|
|
|
|
|
|
you use CPAN to store your preferred settings and install them into your |
|
716
|
|
|
|
|
|
|
projects just like a regular dependency. |
|
717
|
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
use DDP profile => 'ProfileName'; |
|
719
|
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
See L<Data::Printer::Profile> for all the ways to load a profile, a list |
|
721
|
|
|
|
|
|
|
of available profiles and how to make one yourself. |
|
722
|
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
=head2 Filters |
|
725
|
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
Data::Printer works by passing your variable to a different set of filters, |
|
727
|
|
|
|
|
|
|
depending on whether it's a scalar, a hash, an array, an object, etc. It |
|
728
|
|
|
|
|
|
|
comes bundled with filters for all native data types (always enabled, but |
|
729
|
|
|
|
|
|
|
overwritable), including a generic object filter that pretty-prints regular |
|
730
|
|
|
|
|
|
|
and Moo(se) objects and is even aware of Role::Tiny. |
|
731
|
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
Data::Printer also comes with filter bundles that can be quickly activated |
|
733
|
|
|
|
|
|
|
to make it easier to debug L<binary data|Data::Printer::Filter::ContentType> |
|
734
|
|
|
|
|
|
|
and many popular CPAN modules that handle |
|
735
|
|
|
|
|
|
|
L<date and time|Data::Printer::Filter::DateTime>, |
|
736
|
|
|
|
|
|
|
L<databases|Data::Printer::Filter::DB> (yes, even DBIx::Class), |
|
737
|
|
|
|
|
|
|
L<message digests|Data::Printer::Filter::Digest> like MD5 and SHA1, and |
|
738
|
|
|
|
|
|
|
L<JSON and Web|Data::Printer::Filter::Web> content like HTTP requests and |
|
739
|
|
|
|
|
|
|
responses. |
|
740
|
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
So much so we recommend everyone to activate all bundled filters by putting |
|
742
|
|
|
|
|
|
|
the following line on your C<.dataprinter> file: |
|
743
|
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
filters = ContentType, DateTime, DB, Digest, Web |
|
745
|
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
Creating your custom filters is very easy, and |
|
747
|
|
|
|
|
|
|
you're encouraged to upload them to CPAN. There are many options available |
|
748
|
|
|
|
|
|
|
under the C<< Data::Printer::Filter::* >> namespace. Check |
|
749
|
|
|
|
|
|
|
L<Data::Printer::Filter> for more information! |
|
750
|
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
=head2 Making your classes DDP-aware (without adding any dependencies!) |
|
753
|
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
The default object filter will first check if the class implements a sub |
|
755
|
|
|
|
|
|
|
called 'C<_data_printer()>' (or whatever you set the "class_method" option |
|
756
|
|
|
|
|
|
|
to in your settings). If so, Data::Printer will use it to get the string to |
|
757
|
|
|
|
|
|
|
print instead of making a regular class dump. |
|
758
|
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
This means you could have the following in one of your classes: |
|
760
|
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
sub _data_printer { |
|
762
|
|
|
|
|
|
|
my ($self, $ddp) = @_; |
|
763
|
|
|
|
|
|
|
return 'Hey, no peeking! But foo contains ' . $self->foo; |
|
764
|
|
|
|
|
|
|
} |
|
765
|
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
Notice that B<< you can do this without adding Data::Printer as a dependency >> |
|
767
|
|
|
|
|
|
|
to your project! Just write your sub and it will be called with the object to |
|
768
|
|
|
|
|
|
|
be printed and a C<$ddp> object ready for you. See |
|
769
|
|
|
|
|
|
|
L<< Data::Printer::Object|Data::Printer::Object/"Methods and Accessors for Filter Writers" >> |
|
770
|
|
|
|
|
|
|
for how to use it to pretty-print your data. |
|
771
|
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
Finally, if your object implements string overload or provides a method called |
|
773
|
|
|
|
|
|
|
"to_string", "as_string" or "stringify", Data::Printer will use it. To disable |
|
774
|
|
|
|
|
|
|
this behaviour, set C<< class.stringify = 0 >> on your C<.dataprinter> |
|
775
|
|
|
|
|
|
|
file, or call p() with C<< class => { stringify => 0 } >>. |
|
776
|
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
Loading a filter for that particular class will of course override these settings. |
|
778
|
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
=head1 CAVEATS |
|
781
|
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
You can't pass more than one variable at a time. |
|
783
|
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
p $foo, $bar; # wrong |
|
785
|
|
|
|
|
|
|
p $foo; p $bar; # right |
|
786
|
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
You can't use it in variable declarations (it will most likely not do what |
|
788
|
|
|
|
|
|
|
you want): |
|
789
|
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
p my @array = qw(a b c d); # wrong |
|
791
|
|
|
|
|
|
|
my @array = qw(a b c d); p @array; # right |
|
792
|
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
If you pass a nonexistent key/index to DDP using prototypes, they |
|
794
|
|
|
|
|
|
|
will trigger autovivification: |
|
795
|
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
use DDP; |
|
797
|
|
|
|
|
|
|
my %foo; |
|
798
|
|
|
|
|
|
|
p $foo{bar}; # undef, but will create the 'bar' key (with undef) |
|
799
|
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
my @x; |
|
801
|
|
|
|
|
|
|
p $x[5]; # undef, but will initialize the array with 5 elements (all undef) |
|
802
|
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
Slices (both array and hash) must be coerced into actual arrays (or hashes) |
|
804
|
|
|
|
|
|
|
to properly shown. So if you want to print a slice, instead of doing something |
|
805
|
|
|
|
|
|
|
like this: |
|
806
|
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
p @somevar[1..10]; # WRONG! DON'T DO THIS! |
|
808
|
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
try one of those: |
|
810
|
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
my @x = @somevar[1..10]; p @x; # works! |
|
812
|
|
|
|
|
|
|
p [ @somevar[1..0] ]->@*; # also works! |
|
813
|
|
|
|
|
|
|
p @{[@somevar[1..0]]}; # this works too!! |
|
814
|
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
Finally, as mentioned before, you cannot pass anonymous references on the |
|
816
|
|
|
|
|
|
|
default mode of C<< use_prototypes = 1 >>: |
|
817
|
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
p { foo => 1 }; # wrong! |
|
819
|
|
|
|
|
|
|
p %{{ foo => 1 }}; # right |
|
820
|
|
|
|
|
|
|
p { foo => 1 }->%*; # right on perl 5.24+ |
|
821
|
|
|
|
|
|
|
&p( { foo => 1 } ); # right, but requires the parenthesis |
|
822
|
|
|
|
|
|
|
sub pp { p @_ }; # wrapping it also lets you use anonymous data. |
|
823
|
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
use DDP use_prototypes => 0; |
|
825
|
|
|
|
|
|
|
p { foo => 1 }; # works, but now p(@foo) will fail, you must always pass a ref, |
|
826
|
|
|
|
|
|
|
# e.g. p(\@foo) |
|
827
|
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
=head1 BACKWARDS INCOMPATIBLE CHANGES |
|
829
|
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
While we make a genuine effort not to break anything on new releases, |
|
831
|
|
|
|
|
|
|
sometimes we do. To make things easier for people migrating their |
|
832
|
|
|
|
|
|
|
code, we have aggregated here a list of all incompatible changes since ever: |
|
833
|
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
=over 4 |
|
835
|
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
=item * 1.00 - some defaults changed! |
|
837
|
|
|
|
|
|
|
Because we added a bunch of new features (including color themes), you may |
|
838
|
|
|
|
|
|
|
notice some difference on the default output of Data::Printer. Hopefully it's |
|
839
|
|
|
|
|
|
|
for the best. |
|
840
|
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
=item * 1.00 - new C<.dataprinter> file format. |
|
842
|
|
|
|
|
|
|
I<< This should only affect you if you have a C<.dataprinter> file. >> |
|
843
|
|
|
|
|
|
|
The change was required to avoid calling C<eval> on potentially tainted/unknown |
|
844
|
|
|
|
|
|
|
code. It also provided a much cleaner interface. |
|
845
|
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
=item * 1.00 - new way of creating external filters. |
|
847
|
|
|
|
|
|
|
I<< This only affects you if you write or use external filters. >> |
|
848
|
|
|
|
|
|
|
Previously, the sub in your C<filters> call would get the reference to be |
|
849
|
|
|
|
|
|
|
parsed and a properties hash. The properties hash has been replaced with a |
|
850
|
|
|
|
|
|
|
L<Data::Printer::Object> instance, providing much more power and flexibility. |
|
851
|
|
|
|
|
|
|
Because of that, the filter call does not export C<p()>/C<np()> anymore, |
|
852
|
|
|
|
|
|
|
replaced by methods in Data::Printer::Object. |
|
853
|
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
=item * 1.00 - new way to call filters. |
|
855
|
|
|
|
|
|
|
I<< This affects you if you load your own inline filters >>. |
|
856
|
|
|
|
|
|
|
The fix is quick and Data::Printer will generate a warning explaining how |
|
857
|
|
|
|
|
|
|
to do it. Basically, C<< filters => { ... } >> became |
|
858
|
|
|
|
|
|
|
C<< filters => [{ ... }] >> and you must replace C<< -external => [1,2] >> |
|
859
|
|
|
|
|
|
|
with C<< filters => [1, 2] >>, or C<< filters => [1, 2, {...}] >> if you |
|
860
|
|
|
|
|
|
|
also have inline filters. This allowed us much more power and flexibility |
|
861
|
|
|
|
|
|
|
with filters, and hopefully also makes things clearer. |
|
862
|
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
=item * 0.36 - C<p()>'s default return value changed from 'dump' to 'pass'. |
|
864
|
|
|
|
|
|
|
This was a very important change to ensure chained calls and to prevent |
|
865
|
|
|
|
|
|
|
weird side-effects when C<p()> is the last statement in a sub. |
|
866
|
|
|
|
|
|
|
L<< Read the full discussion|https://github.com/garu/Data-Printer/issues/16 >>. |
|
867
|
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
=back |
|
869
|
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
Any undocumented change was probably unintended. If you bump into one, |
|
871
|
|
|
|
|
|
|
please file an issue on Github! |
|
872
|
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
=head1 TIPS & TRICKS |
|
874
|
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
=head2 Using p() in some/all of your loaded modules |
|
876
|
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
I<< (contributed by Matt S. Trout (mst)) >> |
|
878
|
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
While debugging your software, you may want to use Data::Printer in some or |
|
880
|
|
|
|
|
|
|
all loaded modules and not bother having to load it in each and every one of |
|
881
|
|
|
|
|
|
|
them. To do this, in any module loaded by C<myapp.pl>, simply write: |
|
882
|
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
::p @myvar; # note the '::' in front of p() |
|
884
|
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
Then call your program like: |
|
886
|
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
perl -MDDP myapp.pl |
|
888
|
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
This also has the advantage that if you leave one p() call in by accident, |
|
890
|
|
|
|
|
|
|
it will trigger a compile-time failure without the -M, making it easier to |
|
891
|
|
|
|
|
|
|
spot :) |
|
892
|
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
If you really want to have p() imported into your loaded modules, use the |
|
894
|
|
|
|
|
|
|
next tip instead. |
|
895
|
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
=head2 Adding p() to all your loaded modules |
|
897
|
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
I<< (contributed by Árpád Szász) >> |
|
899
|
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
If you wish to automatically add Data::Printer's C<p()> function to |
|
901
|
|
|
|
|
|
|
every loaded module in you app, you can do something like this to |
|
902
|
|
|
|
|
|
|
your main program: |
|
903
|
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
BEGIN { |
|
905
|
|
|
|
|
|
|
{ |
|
906
|
|
|
|
|
|
|
no strict 'refs'; |
|
907
|
|
|
|
|
|
|
require Data::Printer; |
|
908
|
|
|
|
|
|
|
my $alias = 'p'; |
|
909
|
|
|
|
|
|
|
foreach my $package ( keys %main:: ) { |
|
910
|
|
|
|
|
|
|
if ( $package =~ m/::$/ ) { |
|
911
|
|
|
|
|
|
|
*{ $package . $alias } = \&Data::Printer::p; |
|
912
|
|
|
|
|
|
|
} |
|
913
|
|
|
|
|
|
|
} |
|
914
|
|
|
|
|
|
|
} |
|
915
|
|
|
|
|
|
|
} |
|
916
|
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
B<WARNING> This will override all locally defined subroutines/methods that |
|
918
|
|
|
|
|
|
|
are named C<p>, if they exist, in every loaded module. If you already |
|
919
|
|
|
|
|
|
|
have a subroutine named 'C<p()>', be sure to change C<$alias> to |
|
920
|
|
|
|
|
|
|
something custom. |
|
921
|
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
If you rather avoid namespace manipulation altogether, use the previous |
|
923
|
|
|
|
|
|
|
tip instead. |
|
924
|
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
=head2 Using Data::Printer from the Perl debugger |
|
926
|
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
I<< (contributed by Árpád Szász and Marcel Grünauer (hanekomu)) >> |
|
928
|
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
With L<DB::Pluggable>, you can easily set the perl debugger to use |
|
930
|
|
|
|
|
|
|
Data::Printer to print variable information, replacing the debugger's |
|
931
|
|
|
|
|
|
|
standard C<p()> function. All you have to do is add these lines to |
|
932
|
|
|
|
|
|
|
your C<.perldb> file: |
|
933
|
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
use DB::Pluggable; |
|
935
|
|
|
|
|
|
|
DB::Pluggable->run_with_config( \'[DataPrinter]' ); # note the '\' |
|
936
|
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
Then call the perl debugger as you normally would: |
|
938
|
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
perl -d myapp.pl |
|
940
|
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
Now Data::Printer's C<p()> command will be used instead of the debugger's! |
|
942
|
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
See L<perldebug> for more information on how to use the perl debugger, and |
|
944
|
|
|
|
|
|
|
L<DB::Pluggable> for extra functionality and other plugins. |
|
945
|
|
|
|
|
|
|
|
|
946
|
|
|
|
|
|
|
If you can't or don't want to use DB::Pluggable, or simply want to keep |
|
947
|
|
|
|
|
|
|
the debugger's C<p()> function and add an extended version using |
|
948
|
|
|
|
|
|
|
Data::Printer (let's call it C<px()> for instance), you can add these |
|
949
|
|
|
|
|
|
|
lines to your C<.perldb> file instead: |
|
950
|
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
$DB::alias{px} = 's/px/DB::px/'; |
|
952
|
|
|
|
|
|
|
sub px { |
|
953
|
|
|
|
|
|
|
my $expr = shift; |
|
954
|
|
|
|
|
|
|
require Data::Printer; |
|
955
|
|
|
|
|
|
|
print Data::Printer::p($expr); |
|
956
|
|
|
|
|
|
|
} |
|
957
|
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
Now, inside the Perl debugger, you can pass as reference to C<px> expressions |
|
959
|
|
|
|
|
|
|
to be dumped using Data::Printer. |
|
960
|
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=head2 Using Data::Printer in a perl shell (REPL) |
|
962
|
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
Some people really enjoy using a REPL shell to quickly try Perl code. One |
|
964
|
|
|
|
|
|
|
of the most popular ones out there are L<Reply> and L<Devel::REPL>. If you |
|
965
|
|
|
|
|
|
|
use them, now you can also see its output with Data::Printer! |
|
966
|
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
=over 4 |
|
968
|
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
=item * B<Reply> |
|
970
|
|
|
|
|
|
|
|
|
971
|
|
|
|
|
|
|
=back |
|
972
|
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
Just install L<Reply::Plugin::DataPrinter> and add a line with |
|
974
|
|
|
|
|
|
|
C<< [DataPrinter] >> to your C<.replyrc> file. That's it! Next time |
|
975
|
|
|
|
|
|
|
you run the 'reply' REPL, Data::Printer will be used to dump variables! |
|
976
|
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
=over 4 |
|
978
|
|
|
|
|
|
|
|
|
979
|
|
|
|
|
|
|
=item * B<Devel::REPL> |
|
980
|
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
=back |
|
982
|
|
|
|
|
|
|
|
|
983
|
|
|
|
|
|
|
Just install L<Devel::REPL::Plugin::DataPrinter> and add the following |
|
984
|
|
|
|
|
|
|
line to your re.pl configuration file (usually ".re.pl/repl.rc" in your |
|
985
|
|
|
|
|
|
|
home dir): |
|
986
|
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
load_plugin('DataPrinter'); |
|
988
|
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
The next time you run C<re.pl>, it should dump all your REPL using |
|
990
|
|
|
|
|
|
|
Data::Printer! |
|
991
|
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
=head2 Easily rendering Data::Printer's output as HTML |
|
993
|
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
To turn Data::Printer's output into HTML, you can do something like: |
|
995
|
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
use HTML::FromANSI; |
|
997
|
|
|
|
|
|
|
use Data::Printer; |
|
998
|
|
|
|
|
|
|
|
|
999
|
|
|
|
|
|
|
my $html_output = ansi2html( np($object, colored => 1) ); |
|
1000
|
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
In the example above, the C<$html_output> variable contains the |
|
1002
|
|
|
|
|
|
|
HTML escaped output of C<p($object)>, so you can print it for |
|
1003
|
|
|
|
|
|
|
later inspection or render it (if it's a web app). |
|
1004
|
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
=head2 Using Data::Printer with Template Toolkit |
|
1006
|
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
I<< (contributed by Stephen Thirlwall (sdt)) >> |
|
1008
|
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
If you use Template Toolkit and want to dump your variables using Data::Printer, |
|
1010
|
|
|
|
|
|
|
install the L<Template::Plugin::DataPrinter> module and load it in your template: |
|
1011
|
|
|
|
|
|
|
|
|
1012
|
|
|
|
|
|
|
[% USE DataPrinter %] |
|
1013
|
|
|
|
|
|
|
|
|
1014
|
|
|
|
|
|
|
The provided methods match those of C<Template::Plugin::Dumper>: |
|
1015
|
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
ansi-colored dump of the data structure in "myvar": |
|
1017
|
|
|
|
|
|
|
[% DataPrinter.dump( myvar ) %] |
|
1018
|
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
html-formatted, colored dump of the same data structure: |
|
1020
|
|
|
|
|
|
|
[% DataPrinter.dump_html( myvar ) %] |
|
1021
|
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
The module allows several customization options, even letting you load it as a |
|
1023
|
|
|
|
|
|
|
complete drop-in replacement for Template::Plugin::Dumper so you don't even have |
|
1024
|
|
|
|
|
|
|
to change your previous templates! |
|
1025
|
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
=head2 Migrating from Data::Dumper to Data::Printer |
|
1027
|
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
If you are porting your code to use Data::Printer instead of |
|
1029
|
|
|
|
|
|
|
Data::Dumper, you could replace: |
|
1030
|
|
|
|
|
|
|
|
|
1031
|
|
|
|
|
|
|
use Data::Dumper; |
|
1032
|
|
|
|
|
|
|
|
|
1033
|
|
|
|
|
|
|
with something like: |
|
1034
|
|
|
|
|
|
|
|
|
1035
|
|
|
|
|
|
|
use Data::Printer; |
|
1036
|
|
|
|
|
|
|
sub Dumper { np @_, colored => 1 } |
|
1037
|
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
this sub will accept multiple variables just like Data::Dumper. |
|
1039
|
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
=head2 Unified interface for Data::Printer and other debug formatters |
|
1041
|
|
|
|
|
|
|
|
|
1042
|
|
|
|
|
|
|
I<< (contributed by Kevin McGrath (catlgrep)) >> |
|
1043
|
|
|
|
|
|
|
|
|
1044
|
|
|
|
|
|
|
If you want a really unified approach to easily flip between debugging |
|
1045
|
|
|
|
|
|
|
outputs, use L<Any::Renderer> and its plugins, |
|
1046
|
|
|
|
|
|
|
like L<Any::Renderer::Data::Printer>. |
|
1047
|
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
=head2 Printing stack traces with arguments expanded using Data::Printer |
|
1049
|
|
|
|
|
|
|
|
|
1050
|
|
|
|
|
|
|
I<< (contributed by Sergey Aleynikov (randir)) >> |
|
1051
|
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
There are times where viewing the current state of a variable is not |
|
1053
|
|
|
|
|
|
|
enough, and you want/need to see a full stack trace of a function call. |
|
1054
|
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
The L<Devel::PrettyTrace> module uses Data::Printer to provide you just |
|
1056
|
|
|
|
|
|
|
that. It exports a C<bt()> function that pretty-prints detailed information |
|
1057
|
|
|
|
|
|
|
on each function in your stack, making it easier to spot any issues! |
|
1058
|
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
=head2 Troubleshooting apps in real time without changing a single line of your code |
|
1060
|
|
|
|
|
|
|
|
|
1061
|
|
|
|
|
|
|
I<< (contributed by Marcel Grünauer (hanekomu)) >> |
|
1062
|
|
|
|
|
|
|
|
|
1063
|
|
|
|
|
|
|
L<dip> is a dynamic instrumentation framework for troubleshooting Perl |
|
1064
|
|
|
|
|
|
|
programs, similar to L<DTrace|http://opensolaris.org/os/community/dtrace/>. |
|
1065
|
|
|
|
|
|
|
In a nutshell, C<dip> lets you create probes for certain conditions |
|
1066
|
|
|
|
|
|
|
in your application that, once met, will perform a specific action. Since |
|
1067
|
|
|
|
|
|
|
it uses Aspect-oriented programming, it's very lightweight and you only |
|
1068
|
|
|
|
|
|
|
pay for what you use. |
|
1069
|
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
C<dip> can be very useful since it allows you to debug your software |
|
1071
|
|
|
|
|
|
|
without changing a single line of your original code. And Data::Printer |
|
1072
|
|
|
|
|
|
|
comes bundled with it, so you can use the C<p()> function to view your |
|
1073
|
|
|
|
|
|
|
data structures too! |
|
1074
|
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
# Print a stack trace every time the name is changed, |
|
1076
|
|
|
|
|
|
|
# except when reading from the database. |
|
1077
|
|
|
|
|
|
|
dip -e 'before { print longmess(np $_->{args}[1], colored => 1) |
|
1078
|
|
|
|
|
|
|
if $_->{args}[1] } call "MyObj::name" & !cflow("MyObj::read")' myapp.pl |
|
1079
|
|
|
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
You can check L<dip>'s own documentation for more information and options. |
|
1081
|
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
=head2 Sample output for color fine-tuning |
|
1083
|
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
I<< (contributed by Yanick Champoux (yanick)) >> |
|
1085
|
|
|
|
|
|
|
|
|
1086
|
|
|
|
|
|
|
The "examples/try_me.pl" file included in this distribution has a sample |
|
1087
|
|
|
|
|
|
|
dump with a complex data structure to let you quickly test color schemes. |
|
1088
|
|
|
|
|
|
|
|
|
1089
|
|
|
|
|
|
|
=head1 VERSIONING AND UPDATES |
|
1090
|
|
|
|
|
|
|
|
|
1091
|
|
|
|
|
|
|
As of 1.0.0 this module complies with C<Major.Minor.Revision> versioning |
|
1092
|
|
|
|
|
|
|
scheme (SemVer), meaning backwards incompatible changes will trigger a new |
|
1093
|
|
|
|
|
|
|
major number, new features without any breaking changes trigger a new minor |
|
1094
|
|
|
|
|
|
|
number, and simple patches trigger a revision number. |
|
1095
|
|
|
|
|
|
|
|
|
1096
|
|
|
|
|
|
|
=head1 CONTRIBUTORS |
|
1097
|
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
Many thanks to everyone who helped design and develop this module with |
|
1099
|
|
|
|
|
|
|
patches, bug reports, wishlists, comments and tests. They are (alphabetically): |
|
1100
|
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
Adam Rosenstein, Alexandr Ciornii (chorny), Alexander Hartmaier (abraxxa), |
|
1102
|
|
|
|
|
|
|
Allan Whiteford, Anatoly (Snelius30), Andre Klärner, Andreas König (andk), |
|
1103
|
|
|
|
|
|
|
Andy Bach, Anthony DeRobertis, Árpád Szász, Athanasios Douitsis (aduitsis), |
|
1104
|
|
|
|
|
|
|
Baldur Kristinsson, Benct Philip Jonsson (bpj), brian d foy, |
|
1105
|
|
|
|
|
|
|
Chad Granum (exodist), Chris Prather (perigrin), Curtis Poe (Ovid), |
|
1106
|
|
|
|
|
|
|
David D Lowe (Flimm), David E. Condon (hhg7), David Golden (xdg), |
|
1107
|
|
|
|
|
|
|
David Precious (bigpresh), David Raab, David E. Wheeler (theory), |
|
1108
|
|
|
|
|
|
|
Damien Krotkine (dams), Denis Howe, dirk, Dotan Dimet, Eden Cardim (edenc), |
|
1109
|
|
|
|
|
|
|
Elliot Shank (elliotjs), Elvin Aslanov, Eugen Konkov (KES777), |
|
1110
|
|
|
|
|
|
|
Fernando Corrêa (SmokeMachine), Fitz Elliott, Florian Schlichting (fschlich), |
|
1111
|
|
|
|
|
|
|
Frew Schmidt (frew), GianniGi, Graham Knop (haarg), Graham Todd, |
|
1112
|
|
|
|
|
|
|
Gregory J. Oschwald, grr, Håkon Hægland, Iaroslav O. Kosmina (darviarush), |
|
1113
|
|
|
|
|
|
|
Ivan Bessarabov (bessarabv), J Mash, James E. Keenan (jkeenan), |
|
1114
|
|
|
|
|
|
|
Jarrod Funnell (Timbus), Jay Allen (jayallen), Jay Hannah (jhannah), jcop, |
|
1115
|
|
|
|
|
|
|
Jesse Luehrs (doy), Joel Berger (jberger), John S. Anderson (genehack), |
|
1116
|
|
|
|
|
|
|
Karen Etheridge (ether), Kartik Thakore (kthakore), Kevin Dawson (bowtie), |
|
1117
|
|
|
|
|
|
|
Kevin McGrath (catlgrep), Kip Hampton (ubu), Londran, |
|
1118
|
|
|
|
|
|
|
Marcel Grünauer (hanekomu), Marco Masetti (grubert65), Mark Fowler (Trelane), |
|
1119
|
|
|
|
|
|
|
Martin J. Evans, Matthias Muth, Matt S. Trout (mst), Maxim Vuets, Michael Conrad, |
|
1120
|
|
|
|
|
|
|
Mike Doherty (doherty), Nicolas R (atoomic), Nigel Metheringham (nigelm), |
|
1121
|
|
|
|
|
|
|
Nuba Princigalli (nuba), Olaf Alders (oalders), Paul Evans (LeoNerd), |
|
1122
|
|
|
|
|
|
|
Pedro Melo (melo), Philippe Bruhat (BooK), Przemysław Wesołek (jest), |
|
1123
|
|
|
|
|
|
|
Rebecca Turner (iarna), Renato Cron (renatoCRON), Ricardo Signes (rjbs), |
|
1124
|
|
|
|
|
|
|
Rob Hoelz (hoelzro), Salve J. Nilsen (sjn), sawyer, Sebastian Willing (Sewi), |
|
1125
|
|
|
|
|
|
|
Sébastien Feugère (smonff), Sergey Aleynikov (randir), Slaven Rezić, |
|
1126
|
|
|
|
|
|
|
Stanislaw Pusep (syp), Stephen Thirlwall (sdt), sugyan, Tai Paul, |
|
1127
|
|
|
|
|
|
|
Tatsuhiko Miyagawa (miyagawa), Thomas Sibley (tsibley), |
|
1128
|
|
|
|
|
|
|
Tim Heaney (oylenshpeegul), Toby Inkster (tobyink), Torsten Raudssus (Getty), |
|
1129
|
|
|
|
|
|
|
Tokuhiro Matsuno (tokuhirom), trapd00r, Tsai Chung-Kuan, |
|
1130
|
|
|
|
|
|
|
Veesh Goldman (rabbiveesh), vividsnow, Wesley Dal`Col (blabos), y, |
|
1131
|
|
|
|
|
|
|
Yanick Champoux (yanick). |
|
1132
|
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
If I missed your name, please drop me a line! |
|
1134
|
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
|
1136
|
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
Copyright (C) 2011-2024 Breno G. de Oliveira |
|
1138
|
|
|
|
|
|
|
|
|
1139
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
|
1140
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
|
1141
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
|
1142
|
|
|
|
|
|
|
|
|
1143
|
|
|
|
|
|
|
See L<http://dev.perl.org/licenses/> for more information. |
|
1144
|
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
=head1 DISCLAIMER OF WARRANTY |
|
1146
|
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR |
|
1148
|
|
|
|
|
|
|
THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
|
1149
|
|
|
|
|
|
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
|
1150
|
|
|
|
|
|
|
PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
|
1151
|
|
|
|
|
|
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
1152
|
|
|
|
|
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE |
|
1153
|
|
|
|
|
|
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. |
|
1154
|
|
|
|
|
|
|
SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY |
|
1155
|
|
|
|
|
|
|
SERVICING, REPAIR, OR CORRECTION. |
|
1156
|
|
|
|
|
|
|
|
|
1157
|
|
|
|
|
|
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL |
|
1158
|
|
|
|
|
|
|
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
|
1159
|
|
|
|
|
|
|
REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO |
|
1160
|
|
|
|
|
|
|
YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR |
|
1161
|
|
|
|
|
|
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE |
|
1162
|
|
|
|
|
|
|
SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED |
|
1163
|
|
|
|
|
|
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE |
|
1164
|
|
|
|
|
|
|
SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER |
|
1165
|
|
|
|
|
|
|
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. |