8 use vars
qw( $VERSION @ISA @EXPORT @EXPORT_OK );
10 @ISA = qw( DynaLoader Exporter );
11 @EXPORT = qw( DDumper DDsort DPeek DDisplay DDump DDual DGrow );
12 @EXPORT_OK = qw( triplevar );
13 $] >= 5.007003 and push @EXPORT, "DDump_IO";
15 bootstrap Data
::Peek
$VERSION;
17 ### ############# DDumper () ##################################################
27 V
=> sub { # Sort by value
29 [ sort { $r->{$a} cmp $r->{$b} } keys %$r ];
31 VN
=> sub { # Sort by value numeric
33 [ sort { $r->{$a} <=> $r->{$b} } keys %$r ];
35 VNR
=> sub { # Sort by value numeric reverse
37 [ sort { $r->{$b} <=> $r->{$a} } keys %$r ];
39 VR
=> sub { # Sort by value reverse
41 [ sort { $r->{$b} cmp $r->{$a} } keys %$r ];
43 R
=> sub { # Sort reverse
45 [ reverse sort keys %$r ];
54 $_sortkeys = exists $sk{$_[0]} ?
$sk{$_[0]} : $_[0];
61 foreach my $p (@exp) {
62 exists $sk{$p} and DDsort
($p), next;
66 __PACKAGE__
->export_to_level (1, @etl);
71 local $Data::Dumper
::Sortkeys
= $_sortkeys;
72 local $Data::Dumper
::Indent
= 1;
73 local $Data::Dumper
::Quotekeys
= 0;
74 local $Data::Dumper
::Deparse
= 1;
75 local $Data::Dumper
::Terse
= 1;
76 local $Data::Dumper
::Useqq
= 0; # I want unicode visible
78 my $s = Data
::Dumper
::Dumper
@_;
79 $s =~ s/^(\s*)(.*?)\s*=>/sprintf "%s%-16s =>", $1, $2/gme; # Align =>
80 $s =~ s/\bbless\s*\(\s*/bless (/gm and $s =~ s/\s+\)([;,])$/)$1/gm;
81 $s =~ s/^(?= *[]}](?:[;,]|$))/ /gm;
82 $s =~ s/^(\s*[{[]) *\n *(?=\S)(?![{[])/$1 /gm;
83 $s =~ s/^(\s+)/$1$1/gm;
85 defined wantarray or warn $s;
89 ### ############# DDump () ####################################################
95 $has_perlio = ($Config{useperlio
} || "undef") eq "define";
100 my (undef, $down) = (@_, 0);
103 if ($ref eq "SCALAR" || $ref eq "REF") {
104 my %hash = DDump
(${$_[0]}, $down);
107 if ($ref eq "ARRAY") {
109 foreach my $list (@
{$_[0]}) {
110 my %hash = DDump
($list, $down);
111 push @list, { %hash };
115 if ($ref eq "HASH") {
117 foreach my $key (sort keys %{$_[0]}) {
118 $hash{DPeek
($key)} = { DDump
($_[0]->{$key}, $down) };
127 my (undef, $down, $dump, $fh) = (@_, "");
129 if ($has_perlio and open $fh, ">", \
$dump) {
130 #print STDERR "Using DDump_IO\n";
131 DDump_IO
($fh, $_[0], $down);
135 #print STDERR "Using DDump_XS\n";
136 $dump = DDump_XS
($_[0]);
144 my (undef, $down) = (@_, 0);
145 my @dump = split m/[\r\n]+/, _DDump
($_[0], wantarray || $down) or return;
149 ($hash{sv
} = $dump[0]) =~ s/^SV\s*=\s*//;
150 m/^\s+(\w+)\s*=\s*(.*)/ and $hash{$1} = $2 for @dump;
152 if (exists $hash{FLAGS
}) {
153 $hash{FLAGS
} =~ tr/()//d;
154 $hash{FLAGS
} = { map { $_ => 1 } split m/,/ => $hash{FLAGS
} };
157 $down && ref $_[0] and
158 $hash{RV
} = _DDump_ref
($_[0], $down - 1) || $_[0];
162 my $dump = join "\n", @dump, "";
164 defined wantarray and return $dump;
175 Data::Peek - A collection of low-level debug facilities
181 print DDumper \%hash; # Same syntax as Data::Dumper
184 my ($pv, $iv, $nv, $rv, $magic) = DDual ($var [, 1]);
185 print DPeek for DDual ($!, 1);
186 print DDisplay ("ab\nc\x{20ac}\rdef\n");
188 my $dump = DDump $var;
189 my %hash = DDump \@list;
192 my %hash = DDump (\%hash, 5); # dig 5 levels deep
195 open my $fh, ">", \$dump;
196 DDump_IO ($fh, \%hash, 6);
200 use Data::Peek qw( DGrow triplevar );
201 my $x = ""; DGrow ($x, 10000);
202 my $tv = triplevar ("\N{GREEK SMALL LETTER PI}", 3, "3.1415");
206 Data::Peek started off as C<DDumper> being a wrapper module over
207 L<Data::Dumper>, but grew out to be a set of low-level data
208 introspection utilities that no other module provided yet, using the
209 lowest level of the perl internals API as possible.
211 =head2 DDumper ($var, ...)
213 Not liking the default output of Data::Dumper, and always feeling the need
214 to set C<$Data::Dumper::Sortkeys = 1;>, and not liking any of the default
215 layouts, this function is just a wrapper around Data::Dumper::Dumper with
216 everything set as I like it.
218 $Data::Dumper::Sortkeys = 1;
219 $Data::Dumper::Indent = 1;
221 And the result is further beautified to meet my needs:
223 * quotation of hash keys has been removed (with the disadvantage
224 that the output might not be parseable again).
225 * arrows for hashes are aligned at 16 (longer keys don't align)
226 * closing braces and brackets are now correctly aligned
228 In void context, C<DDumper ()> warn ()'s.
232 print DDumper { ape => 1, foo => "egg", bar => [ 2, "baz", undef ]};
243 =head2 DDsort ( 0 | 1 | R | V | VR | VN | VNR )
245 Set the hash sort algorithm for DDumper. The default is to sort by key value.
249 R - Reverse sort by key
251 VR - Reverse sort by value
252 VN - Sort by value numerical
253 VNR - Reverse sort by value numerical
255 These can also be passed to import:
257 $ perl -MDP=VNR -we'DDumper { foo => 1, bar => 2, zap => 3, gum => 13 }'
263 $ perl -MDP=V -we'DDumper { foo => 1, bar => 2, zap => 3, gum => 13 }'
274 Playing with C<sv_dump ()>, I found C<Perl_sv_peek ()>, and it might be
275 very useful for simple checks. If C<$var> is omitted, uses $_.
279 print DPeek "abc\x{0a}de\x{20ac}fg";
281 PV("abc\nde\342\202\254fg"\0) [UTF8 "abc\nde\x{20ac}fg"]
283 In void context, C<DPeek ()> prints to C<STDERR> plus a newline.
287 =head2 DDisplay ($var)
289 Show the PV content of a scalar the way perl debugging would have done.
290 UTF-8 detection is on, so this is effectively the same as returning the
291 first part the C<DPeek ()> returns for non-UTF8 PV's or the second part
292 for UTF-8 PV's. C<DDisplay ()> returns the empty string for scalars that
297 print DDisplay "abc\x{0a}de\x{20ac}fg";
301 =head2 my ($pv, $iv, $nv, $rv, $hm) = DDual ($var [, $getmagic])
303 DDual will return the basic elements in a variable, guaranteeing that no
304 conversion takes place. This is very useful for dual-var variables, or
305 when checking is a variable has defined entries for a certain type of
306 scalar. For each String (PV), Integer (IV), Double (NV), and Reference (RV),
307 the current value of C<$var> is returned or undef if it is not set (yet).
308 The 5th element is an indicator if C<$var> has magic, which is B<not> invoked
309 in the returned values, unless explicitly asked for with a true optional
314 print DPeek for DDual ($!, 1);
316 In void context, DDual does the equivalent of
318 { my @d = DDual ($!, 1);
321 " PV: ", DPeek ($d[0]), "\n",
322 " IV: ", DPeek ($d[1]), "\n",
323 " NV: ", DPeek ($d[2]), "\n",
324 " RV: ", DPeek ($d[3]), "\n";
327 =head2 my $LEN = DGrow ($pv, $size)
329 Fastest way to preallocate space for a PV scalar. Returns the allocated
330 length. If $size is smaller than the already allocated space, it will
334 pack => q{my $x = ""; $x = pack "x20000"; $x = "";},
335 op_x => q{my $x = ""; $x = "x" x 20000; $x = "";},
336 grow => q{my $x = ""; DGrow ($x, 20000); $x = "";},
340 op_x 62127/s -- -59% -96%
341 pack 152046/s 145% -- -91%
342 grow 1622943/s 2512% 967% --
345 =head2 triplevar ($pv, $iv, $nv)
347 When making C<DDual ()> I wondered if it were possible to create triple-val
348 scalar variables. L<Scalar::Util> already gives us C<dualvar ()>, that creates
349 you a scalar with different numeric and string values that return different
350 values in different context. Not that C<triplevar ()> would be very useful,
351 compared to C<dualvar ()>, but at least this shows that it is possible.
353 C<triplevar ()> is not exported by default.
357 print DPeek for DDual
358 Data::Peek::triplevar ("\N{GREEK SMALL LETTER PI}", 3, 3.1415);
360 PV("\317\200"\0) [UTF8 "\x{3c0}"]
366 =head2 DDump ($var [, $dig_level])
368 A very useful module when debugging is C<Devel::Peek>, but is has one big
369 disadvantage: it only prints to STDERR, which is not very handy when your
370 code wants to inspect variables al a low level.
372 Perl itself has C<sv_dump ()>, which does something similar, but still
373 prints to STDERR, and only one level deep.
375 C<DDump ()> is an attempt to make the innards available to the script level
376 with a reasonable level of compatibility. C<DDump ()> is context sensitive.
378 In void context, it behaves exactly like C<Perl_sv_dump ()>.
380 In scalar context, it returns what C<Perl_sv_dump ()> would have printed.
382 In list context, it returns a hash of the variable's properties. In this mode
383 you can pass an optional second argument that determines the depth of digging.
387 print scalar DDump "abc\x{0a}de\x{20ac}fg"
389 SV = PV(0x723250) at 0x8432b0
391 FLAGS = (PADBUSY,PADMY,POK,pPOK,UTF8)
392 PV = 0x731ac0 "abc\nde\342\202\254fg"\0 [UTF8 "abc\nde\x{20ac}fg"]
396 my %h = DDump "abc\x{0a}de\x{20ac}fg";
408 PV => '0x731ac0 "abc\\nde\\342\\202\\254fg"\\0 [UTF8 "abc\\nde\\x{20ac}fg"]',
410 sv => 'PV(0x723250) at 0x8432c0'
416 bar => [ 2, "baz", undef ],
436 sv => 'IV(0x747020) at 0x843a10'
450 sv => 'PVIV(0x7223e0) at 0x843a10'
462 PV => '0x7496c0 "egg"\\0',
464 sv => 'PVIV(0x7223e0) at 0x843a10'
467 sv => 'RV(0x79d058) at 0x843310'
470 =head2 DDump_IO ($io, $var [, $dig_level])
472 A wrapper function around perl's internal C<Perl_do_sv_dump ()>, which
473 makes C<Devel::Peek> completely superfluous. As PerlIO is only available
474 perl version 5.7.3 and up, this function is not available in older perls.
479 open my $eh, ">", \$dump;
480 DDump_IO ($eh, { 3 => 4, ape => [5..8]}, 6);
484 SV = RV(0x79d9e0) at 0x843f00
488 SV = PVHV(0x79c948) at 0x741090
493 ARRAY = 0x748ff0 (0:7, 2:1)
500 Elt "ape" HASH = 0x97623e03
501 SV = RV(0x79d9d8) at 0x8440e0
505 SV = PVAV(0x7264b0) at 0x741470
516 SV = IV(0x7467c8) at 0x7c1aa0
521 SV = IV(0x7467b0) at 0x8440f0
526 SV = IV(0x746810) at 0x75be00
531 SV = IV(0x746d38) at 0x7799d0
535 Elt "3" HASH = 0xa400c7f3
536 SV = IV(0x746fd0) at 0x7200e0
543 C<DDump ()> uses an XS wrapper around C<Perl_sv_dump ()> where the
544 STDERR is temporarily caught to a pipe. The internal XS helper functions
545 are not meant for user space
547 =head2 DDump_XS (SV *sv)
549 Base interface to internals for C<DDump ()>.
553 Windows and AIX might be using a build where not all symbols that were
554 supposed to be exported in the public API are not. Perl_pv_peek () is
557 Not all types of references are supported.
559 No idea how far back this goes in perl support, but Devel::PPPort has
560 proven to be a big help.
564 L<Devel::Peek(3)>, L<Data::Dumper(3)>, L<Data::Dump(3)>, L<Devel::Dumpvar>,
565 L<Data::Dump::Streamer(3)>
569 H.Merijn Brand <h.m.brand@xs4all.nl>
571 =head1 COPYRIGHT AND LICENSE
573 Copyright (C) 2008-2010 H.Merijn Brand
575 This library is free software; you can redistribute it and/or modify
576 it under the same terms as Perl itself.