8 use vars
qw( $VERSION @ISA @EXPORT @EXPORT_OK );
10 @ISA = qw( DynaLoader Exporter );
11 @EXPORT = qw( DDumper DTidy DDsort DPeek DDisplay DDump DHexDump
13 @EXPORT_OK = qw( triplevar :tidy );
14 push @EXPORT, "DDump_IO";
16 bootstrap Data
::Peek
$VERSION;
23 $has_perlio = ($Config{useperlio
} || "undef") eq "define";
24 $has_perltidy = eval q{use Perl::Tidy; $Perl::Tidy::VERSION};
27 ### ############# DDumper () ##################################################
37 V => sub { # Sort by value
39 [ sort { $r->{$a} cmp $r->{$b} } keys %$r ];
41 VN => sub { # Sort by value numeric
43 [ sort { $r->{$a} <=> $r->{$b} } keys %$r ];
45 VNR => sub { # Sort by value numeric reverse
47 [ sort { $r->{$b} <=> $r->{$a} } keys %$r ];
49 VR => sub { # Sort by value reverse
51 [ sort { $r->{$b} cmp $r->{$a} } keys %$r ];
53 R => sub { # Sort reverse
55 [ reverse sort keys %$r ];
65 $_sortkeys = exists $sk{$_[0]} ? $sk{$_[0]} : $_[0];
72 foreach my $p (@exp) {
73 exists $sk{$p} and DDsort ($p), next;
76 $_perltidy = $has_perltidy;
82 __PACKAGE__->export_to_level (1, @etl);
87 $_perltidy and goto \&DTidy;
89 local $Data::Dumper::Sortkeys = $_sortkeys;
90 local $Data::Dumper::Indent = 1;
91 local $Data::Dumper::Quotekeys = 0;
92 local $Data::Dumper::Deparse = 1;
93 local $Data::Dumper::Terse = 1;
94 local $Data::Dumper::Useqq = 0; # I want unicode visible
96 my $s = Data::Dumper::Dumper @_;
97 $s =~ s/^(\s*)(.*?)\s*=>/sprintf "%s%-16s =>", $1, $2/gme; # Align =>
98 $s =~ s/\bbless\s*\(\s*/bless (/gm and $s =~ s/\s+\)([;,])$/)$1/gm;
99 $s =~ s/^(?=\s*[]}](?:[;,]|$))/ /gm;
100 $s =~ s/^(\s*[{[]) *\n *(?=\S)(?![{[])/$1 /gm;
101 $s =~ s/^(\s+)/$1$1/gm;
103 defined wantarray or warn $s;
109 $has_perltidy or goto \&DDumper;
111 local $Data::Dumper::Sortkeys = $_sortkeys;
112 local $Data::Dumper::Indent = 1;
113 local $Data::Dumper::Quotekeys = 1;
114 local $Data::Dumper::Deparse = 1;
115 local $Data::Dumper::Terse = 1;
116 local $Data::Dumper::Useqq = 0;
118 my $s = Data::Dumper::Dumper @_;
120 Perl::Tidy::perltidy (source => \$s, destination => \$t, argv => [
121 # Disable stupid options in ~/.perltidyrc
122 # people do so, even for root
123 "--no-backup-and-modify-in-place",
125 "--no-standard-output",
126 "--no-warning-output",
127 # RT#99514 - Perl::Tidy memoizes .perltidyrc incorrectly
132 defined wantarray or warn $s;
136 ### ############# DDump () ####################################################
140 my (undef, $down) = (@_, 0);
143 if ($ref eq "SCALAR" || $ref eq "REF") {
144 my %hash = DDump (${$_[0]}, $down);
147 if ($ref eq "ARRAY") {
149 foreach my $list (@{$_[0]}) {
150 my %hash = DDump ($list, $down);
151 push @list, { %hash };
155 if ($ref eq "HASH") {
157 foreach my $key (sort keys %{$_[0]}) {
158 $hash{DPeek ($key)} = { DDump ($_[0]->{$key}, $down) };
167 my (undef, $down, $dump, $fh) = (@_, "");
169 if ($has_perlio and open $fh, ">", \$dump) {
170 #print STDERR "Using DDump_IO\n";
171 DDump_IO ($fh, $_[0], $down);
175 #print STDERR "Using DDump_XS\n";
176 $dump = DDump_XS ($_[0]);
184 my (undef, $down) = (@_, 0);
185 my @dump = split m/[\r\n]+/, _DDump ($_[0], wantarray || $down) or return;
189 ($hash{sv} = $dump[0]) =~ s/^SV\s*=\s*//;
190 m/^\s+(\w+)\s*=\s*(.*)/ and $hash{$1} = $2 for @dump;
192 if (exists $hash{FLAGS}) {
193 $hash{FLAGS} =~ tr/()//d;
194 $hash{FLAGS} = { map { $_ => 1 } split m/,/ => $hash{FLAGS} };
197 $down && ref $_[0] and
198 $hash{RV} = _DDump_ref ($_[0], $down - 1) || $_[0];
202 my $dump = join "\n", @dump, "";
204 defined wantarray and return $dump;
214 my $var = @_ ? $_[0] : $_;
215 defined $var or return;
216 my $fmt = @_ > 1 && $_[1] < length ($var) ? "A$_[1]" : "A*";
217 my $str = pack $fmt, $var; # force stringification
218 for (unpack "(A32)*", unpack "H*", $str) {
219 my @b = unpack "(A2)*", $_;
220 my $out = sprintf "%04x ", $off;
221 $out .= " ".($b[$_]||" ") for 0 .. 7;
223 $out .= " ".($b[$_]||" ") for 8 .. 15;
225 $out .= ($_ < 0x20 || $_ >= 0x7f ? "." : chr $_) for map { hex $_ } @b;
226 push @out, $out."\n";
230 wantarray and return @out;
232 defined wantarray and return join "", @out;
243 Data::Peek - A collection of low-level debug facilities
249 print DDumper \%hash; # Same syntax as Data::Dumper
250 DTidy { ref => $ref };
253 my ($pv, $iv, $nv, $rv, $magic) = DDual ($var [, 1]);
254 print DPeek for DDual ($!, 1);
255 print DDisplay ("ab\nc\x{20ac}\rdef\n");
256 print DHexDump ("ab\nc\x{20ac}\rdef\n");
258 my $dump = DDump $var;
259 my %hash = DDump \@list;
262 my %hash = DDump (\%hash, 5); # dig 5 levels deep
265 open my $fh, ">", \$dump;
266 DDump_IO ($fh, \%hash, 6);
271 use Data::Peek qw( :tidy VNR DGrow triplevar );
272 my $x = ""; DGrow
($x, 10000);
273 my $tv = triplevar
("\N{GREEK SMALL LETTER PI}", 3, "3.1415");
275 DDumper
[ $x ]; # use of :tidy make DDumper behave as DTidy
279 Data::Peek started off as C<DDumper> being a wrapper module over
280 L<Data::Dumper>, but grew out to be a set of low-level data
281 introspection utilities that no other module provided yet, using the
282 lowest level of the perl internals API as possible.
284 =head2 DDumper ($var, ...)
286 Not liking the default output of Data::Dumper, and always feeling the need
287 to set C<$Data::Dumper::Sortkeys = 1;>, and not liking any of the default
288 layouts, this function is just a wrapper around Data::Dumper::Dumper with
289 everything set as I like it.
291 $Data::Dumper::Sortkeys = 1;
292 $Data::Dumper::Indent = 1;
294 If C<Data::Peek> is C<use>d with import argument C<:tidy>, the result is
295 formatted according to L<Perl::Tidy>, see L<DTidy> below, otherwise the
296 result is further beautified to meet my needs:
298 * quotation of hash keys has been removed (with the disadvantage
299 that the output might not be parseable again).
300 * arrows for hashes are aligned at 16 (longer keys don't align)
301 * closing braces and brackets are now correctly aligned
303 In void context, C<DDumper ()> warn ()'s.
308 -e'DDumper { ape => 1, foo => "egg", bar => [ 2, "baz", undef ]};'
319 =head2 DTidy ($var, ...)
321 C<DTidy> is an alternative to C<DDumper>, where the output of C<DDumper>
322 is formatted using C<Perl::Tidy> (if available) according to your
323 C<.perltidyrc> instead of the default behavior, maybe somewhat like (YMMV):
326 -we'DDumper { ape => 1, foo => "egg", bar => [ 2, "baz", undef ]};'
328 'bar' => [2, 'baz', undef],
332 If C<Data::Peek> is C<use>d with import argument C<:tidy>, this is the
333 default output method for C<DDumper>.
335 If L<Perl::Tidy> is not available, C<DTidy> will fallback to C<DDumper>.
337 This idea was shamelessly copied from John McNamara's L<Data::Dumper::Perltidy>.
339 =head2 DDsort ( 0 | 1 | R | V | VR | VN | VNR )
341 Set the hash sort algorithm for DDumper. The default is to sort by key value.
345 R - Reverse sort by key
347 VR - Reverse sort by value
348 VN - Sort by value numerical
349 VNR - Reverse sort by value numerical
351 These can also be passed to import:
354 -we'DDumper { foo => 1, bar => 2, zap => 3, gum => 13 }'
361 -we'DDumper { foo => 1, bar => 2, zap => 3, gum => 13 }'
372 Playing with C<sv_dump ()>, I found C<Perl_sv_peek ()>, and it might be
373 very useful for simple checks. If C<$var> is omitted, uses $_.
377 print DPeek "abc\x{0a}de\x{20ac}fg";
379 PV("abc\nde\342\202\254fg"\0) [UTF8 "abc\nde\x{20ac}fg"]
381 In void context, C<DPeek ()> prints to C<STDERR> plus a newline.
385 =head2 DDisplay ($var)
387 Show the PV content of a scalar the way perl debugging would have done.
388 UTF-8 detection is on, so this is effectively the same as returning the
389 first part the C<DPeek ()> returns for non-UTF8 PV's or the second part
390 for UTF-8 PV's. C<DDisplay ()> returns the empty string for scalars that
395 print DDisplay "abc\x{0a}de\x{20ac}fg";
401 =head2 DHexDump ($var)
403 =head2 DHexDump ($var, $length)
405 Show the (stringified) content of a scalar as a hex-dump. If C<$var>
406 is omitted, C<$_> is dumped. Returns C<undef> or an empty list if
407 C<$var> (or C<$_>) is undefined. If C<$length> is given and is lower than
408 the length of the stringified C<$var>, only <$length> bytes are dumped.
410 In void context, the dump is done to STDERR. In scalar context, the
411 complete dump is returned as a single string. In list context, the dump
412 is returned as lines.
416 print DHexDump "abc\x{0a}de\x{20ac}fg";
418 0000 61 62 63 0a 64 65 e2 82 ac 66 67 abc.de...fg
420 =head2 my ($pv, $iv, $nv, $rv, $hm) = DDual ($var [, $getmagic])
422 DDual will return the basic elements in a variable, guaranteeing that no
423 conversion takes place. This is very useful for dual-var variables, or
424 when checking is a variable has defined entries for a certain type of
425 scalar. For each String (PV), Integer (IV), Double (NV), and Reference (RV),
426 the current value of C<$var> is returned or undef if it is not set (yet).
427 The 5th element is an indicator if C<$var> has magic, which is B<not> invoked
428 in the returned values, unless explicitly asked for with a true optional
433 print DPeek for DDual ($!, 1);
435 In void context, DDual does the equivalent of
437 { my @d = DDual ($!, 1);
440 " PV: ", DPeek ($d[0]), "\n",
441 " IV: ", DPeek ($d[1]), "\n",
442 " NV: ", DPeek ($d[2]), "\n",
443 " RV: ", DPeek ($d[3]), "\n";
446 =head2 my $len = DGrow ($pv, $size)
448 Fastest way to preallocate space for a PV scalar. Returns the allocated
449 length. If $size is smaller than the already allocated space, it will
453 pack => q{my $x = ""; $x = pack "x20000"; $x = "";},
454 op_x => q{my $x = ""; $x = "x" x 20000; $x = "";},
455 grow => q{my $x = ""; DGrow ($x, 20000); $x = "";},
458 Rate op_x pack grow 5.8.9 5.10.1 5.12.4 5.14.2
459 op_x 62127/s -- -59% -96% 118606/s 119730/s 352255/s 362605/s
460 pack 152046/s 145% -- -91% 380075/s 355666/s 347247/s 387349/s
461 grow 1622943/s 2512% 967% -- 2818380/s 2918783/s 2672340/s 2886787/s
463 =head2 my $tp = triplevar ($pv, $iv, $nv)
465 When making C<DDual ()> I wondered if it were possible to create triple-val
466 scalar variables. L<Scalar::Util> already gives us C<dualvar ()>, that creates
467 you a scalar with different numeric and string values that return different
468 values in different context. Not that C<triplevar ()> would be very useful,
469 compared to C<dualvar ()>, but at least this shows that it is possible.
471 C<triplevar ()> is not exported by default.
475 print DPeek for DDual
476 Data::Peek::triplevar ("\N{GREEK SMALL LETTER PI}", 3, 3.1415);
478 PV("\317\200"\0) [UTF8 "\x{3c0}"]
484 =head2 DDump ($var [, $dig_level])
486 A very useful module when debugging is C<Devel::Peek>, but is has one big
487 disadvantage: it only prints to STDERR, which is not very handy when your
488 code wants to inspect variables at a low level.
490 Perl itself has C<sv_dump ()>, which does something similar, but still
491 prints to STDERR, and only one level deep.
493 C<DDump ()> is an attempt to make the innards available to the script level
494 with a reasonable level of compatibility. C<DDump ()> is context sensitive.
496 In void context, it behaves exactly like C<Perl_sv_dump ()>.
498 In scalar context, it returns what C<Perl_sv_dump ()> would have printed.
500 In list context, it returns a hash of the variable's properties. In this mode
501 you can pass an optional second argument that determines the depth of digging.
505 print scalar DDump "abc\x{0a}de\x{20ac}fg"
507 SV = PV(0x723250) at 0x8432b0
509 FLAGS = (PADBUSY,PADMY,POK,pPOK,UTF8)
510 PV = 0x731ac0 "abc\nde\342\202\254fg"\0 [UTF8 "abc\nde\x{20ac}fg"]
514 my %h = DDump "abc\x{0a}de\x{20ac}fg";
526 PV => '0x731ac0 "abc\\nde\\342\\202\\254fg"\\0 [UTF8 "abc\\nde\\x{20ac}fg"]',
528 sv => 'PV(0x723250) at 0x8432c0'
534 bar => [ 2, "baz", undef ],
554 sv => 'IV(0x747020) at 0x843a10'
568 sv => 'PVIV(0x7223e0) at 0x843a10'
580 PV => '0x7496c0 "egg"\\0',
582 sv => 'PVIV(0x7223e0) at 0x843a10'
585 sv => 'RV(0x79d058) at 0x843310'
588 =head2 DDump_IO ($io, $var [, $dig_level])
590 A wrapper function around perl's internal C<Perl_do_sv_dump ()>, which
591 makes C<Devel::Peek> completely superfluous.
596 open my $eh, ">", \$dump;
597 DDump_IO ($eh, { 3 => 4, ape => [5..8]}, 6);
601 SV = RV(0x79d9e0) at 0x843f00
605 SV = PVHV(0x79c948) at 0x741090
610 ARRAY = 0x748ff0 (0:7, 2:1)
617 Elt "ape" HASH = 0x97623e03
618 SV = RV(0x79d9d8) at 0x8440e0
622 SV = PVAV(0x7264b0) at 0x741470
633 SV = IV(0x7467c8) at 0x7c1aa0
638 SV = IV(0x7467b0) at 0x8440f0
643 SV = IV(0x746810) at 0x75be00
648 SV = IV(0x746d38) at 0x7799d0
652 Elt "3" HASH = 0xa400c7f3
653 SV = IV(0x746fd0) at 0x7200e0
660 C<DDump ()> uses an XS wrapper around C<Perl_sv_dump ()> where the
661 STDERR is temporarily caught to a pipe. The internal XS helper functions
662 are not meant for user space
664 =head2 DDump_XS (SV *sv)
666 Base interface to internals for C<DDump ()>.
670 Windows and AIX might be using a build where not all symbols that were
671 supposed to be exported in the public API are not. Perl_pv_peek () is
674 Not all types of references are supported.
676 No idea how far back this goes in perl support, but Devel::PPPort has
677 proven to be a big help.
681 L<Devel::Peek>, L<Data::Dumper>, L<Data::Dump>, L<Devel::Dumpvar>,
682 L<Data::Dump::Streamer>, L<Data::Dumper::Perltidy>, L<Perl::Tidy>.
686 H.Merijn Brand <h.m.brand@xs4all.nl>
688 =head1 COPYRIGHT AND LICENSE
690 Copyright (C) 2008-2015 H.Merijn Brand
692 This library is free software; you can redistribute it and/or modify
693 it under the same terms as Perl itself.