File Coverage

blib/lib/Data/Peek.pm
Criterion Covered Total %
statement 108 130 83.0
branch 28 48 58.3
condition 17 30 56.6
subroutine 17 18 94.4
pod 5 5 100.0
total 175 231 75.7


line stmt bran cond sub pod time code
1             package Data::Peek;
2              
3 12     12   344770 use strict;
  12         16  
  12         315  
4 12     12   35 use warnings;
  12         11  
  12         217  
5              
6 12     12   44 use DynaLoader ();
  12         12  
  12         178  
7              
8 12     12   32 use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK );
  12         11  
  12         1190  
9             $VERSION = "0.45";
10             @ISA = qw( DynaLoader Exporter );
11             @EXPORT = qw( DDumper DTidy DDsort DPeek DDisplay DDump DHexDump
12             DDual DGrow );
13             @EXPORT_OK = qw( triplevar :tidy );
14             push @EXPORT, "DDump_IO";
15              
16             bootstrap Data::Peek $VERSION;
17              
18             our $has_perlio;
19             our $has_perltidy;
20              
21             BEGIN {
22 12     12   44 use Config;
  12         12  
  12         602  
23 12   50 12   849 $has_perlio = ($Config{useperlio} || "undef") eq "define";
24 12     12   560 $has_perltidy = eval q{use Perl::Tidy; $Perl::Tidy::VERSION};
  12         41010  
  12         1369039  
  12         974  
25             }
26              
27             ### ############# DDumper () ##################################################
28              
29 12     12   6298 use Data::Dumper;
  12         45749  
  12         11108  
30              
31             my %sk = (
32             undef => 0,
33             "" => 0,
34             0 => 0,
35             1 => 1,
36              
37             V => sub { # Sort by value
38             my $r = shift;
39             [ sort { $r->{$a} cmp $r->{$b} } keys %$r ];
40             },
41             VN => sub { # Sort by value numeric
42             my $r = shift;
43             [ sort { $r->{$a} <=> $r->{$b} } keys %$r ];
44             },
45             VNR => sub { # Sort by value numeric reverse
46             my $r = shift;
47             [ sort { $r->{$b} <=> $r->{$a} } keys %$r ];
48             },
49             VR => sub { # Sort by value reverse
50             my $r = shift;
51             [ sort { $r->{$b} cmp $r->{$a} } keys %$r ];
52             },
53             R => sub { # Sort reverse
54             my $r = shift;
55             [ reverse sort keys %$r ];
56             },
57             );
58             my $_sortkeys = 1;
59             our $_perltidy = 0;
60              
61             sub DDsort
62             {
63 6 50   6 1 9 @_ or return;
64              
65 6 50       26 $_sortkeys = exists $sk{$_[0]} ? $sk{$_[0]} : $_[0];
66             } # DDsort
67              
68             sub import
69             {
70 12     12   77 my @exp = @_;
71 12         13 my @etl;
72 12         17 foreach my $p (@exp) {
73 18 50       49 exists $sk{$p} and DDsort ($p), next;
74              
75 18 100       43 if ($p eq ":tidy") {
76 1         1 $_perltidy = $has_perltidy;
77 1         2 next;
78             }
79              
80 17         24 push @etl, $p;
81             }
82 12         13015 __PACKAGE__->export_to_level (1, @etl);
83             } # import
84              
85             sub DDumper
86             {
87 37 100   37 1 10272 $_perltidy and goto \&DTidy;
88              
89 22         24 local $Data::Dumper::Sortkeys = $_sortkeys;
90 22         19 local $Data::Dumper::Indent = 1;
91 22         18 local $Data::Dumper::Quotekeys = 0;
92 22         22 local $Data::Dumper::Deparse = 1;
93 22         14 local $Data::Dumper::Terse = 1;
94 22         19 local $Data::Dumper::Useqq = 0; # I want unicode visible
95              
96 22         47 my $s = Data::Dumper::Dumper @_;
97 22         3027 $s =~ s/^(\s*)(.*?)\s*=>/sprintf "%s%-16s =>", $1, $2/gme; # Align =>
  26         84  
98 22 50       43 $s =~ s/\bbless\s*\(\s*/bless (/gm and $s =~ s/\s+\)([;,])$/)$1/gm;
99 22         76 $s =~ s/^(?=\s*[]}](?:[;,]|$))/ /gm;
100 22         83 $s =~ s/^(\s*[{[]) *\n *(?=\S)(?![{[])/$1 /gm;
101 22         99 $s =~ s/^(\s+)/$1$1/gm;
102              
103 22 50       35 defined wantarray or warn $s;
104 22         83 return $s;
105             } # DDumper
106              
107             sub DTidy
108             {
109 15 50   15 1 51 $has_perltidy or goto \&DDumper;
110              
111 15         342 local $Data::Dumper::Sortkeys = $_sortkeys;
112 15         28 local $Data::Dumper::Indent = 1;
113 15         26 local $Data::Dumper::Quotekeys = 1;
114 15         32 local $Data::Dumper::Deparse = 1;
115 15         20 local $Data::Dumper::Terse = 1;
116 15         26 local $Data::Dumper::Useqq = 0;
117              
118 15         67 my $s = Data::Dumper::Dumper @_;
119 15         2672 my $t;
120 15         93 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",
124             "--no-check-syntax",
125             "--no-standard-output",
126             "--no-warning-output",
127             # RT#99514 - Perl::Tidy memoizes .perltidyrc incorrectly
128             "--no-memoize",
129             ]);
130 15         946475 $s = $t;
131              
132 15 50       57 defined wantarray or warn $s;
133 15         153 return $s;
134             } # DTidy
135              
136             ### ############# DDump () ####################################################
137              
138             sub _DDump_ref
139             {
140 0     0   0 my (undef, $down) = (@_, 0);
141              
142 0         0 my $ref = ref $_[0];
143 0 0 0     0 if ($ref eq "SCALAR" || $ref eq "REF") {
144 0         0 my %hash = DDump (${$_[0]}, $down);
  0         0  
145 0         0 return { %hash };
146             }
147 0 0       0 if ($ref eq "ARRAY") {
148 0         0 my @list;
149 0         0 foreach my $list (@{$_[0]}) {
  0         0  
150 0         0 my %hash = DDump ($list, $down);
151 0         0 push @list, { %hash };
152             }
153 0         0 return [ @list ];
154             }
155 0 0       0 if ($ref eq "HASH") {
156 0         0 my %hash;
157 0         0 foreach my $key (sort keys %{$_[0]}) {
  0         0  
158 0         0 $hash{DPeek ($key)} = { DDump ($_[0]->{$key}, $down) };
159             }
160 0         0 return { %hash };
161             }
162 0         0 undef;
163             } # _DDump_ref
164              
165             sub _DDump
166             {
167 7     7   11 my (undef, $down, $dump, $fh) = (@_, "");
168              
169 7 100 66 1   61 if ($has_perlio and open $fh, ">", \$dump) {
  1         4  
  1         1  
  1         4  
170             #print STDERR "Using DDump_IO\n";
171 3         712 DDump_IO ($fh, $_[0], $down);
172 3         6 close $fh;
173             }
174             else {
175             #print STDERR "Using DDump_XS\n";
176 4         122 $dump = DDump_XS ($_[0]);
177             }
178              
179 7         56 return $dump;
180             } # _DDump
181              
182             sub DDump ($;$)
183             {
184 7     7 1 3549 my (undef, $down) = (@_, 0);
185 7 50 66     32 my @dump = split m/[\r\n]+/, _DDump ($_[0], wantarray || $down) or return;
186              
187 7 100       13 if (wantarray) {
188 3         2 my %hash;
189 3         22 ($hash{sv} = $dump[0]) =~ s/^SV\s*=\s*//;
190 3   66     54 m/^\s+(\w+)\s*=\s*(.*)/ and $hash{$1} = $2 for @dump;
191              
192 3 50       6 if (exists $hash{FLAGS}) {
193 3         5 $hash{FLAGS} =~ tr/()//d;
194 3         7 $hash{FLAGS} = { map { $_ => 1 } split m/,/ => $hash{FLAGS} };
  7         13  
195             }
196              
197             $down && ref $_[0] and
198 3 50 0     9 $hash{RV} = _DDump_ref ($_[0], $down - 1) || $_[0];
      33        
199 3         24 return %hash;
200             }
201              
202 4         11 my $dump = join "\n", @dump, "";
203              
204 4 50       13 defined wantarray and return $dump;
205              
206 0         0 warn $dump;
207             } # DDump
208              
209             sub DHexDump
210             {
211 12     12   59 use bytes;
  12         17  
  12         39  
212 6     6 1 798 my $off = 0;
213 6         5 my @out;
214 6 50       12 my $var = @_ ? $_[0] : $_;
215 6 100       12 defined $var or return;
216 5 100 66     18 my $fmt = @_ > 1 && $_[1] < length ($var) ? "A$_[1]" : "A*";
217 5         19 my $str = pack $fmt, $var; # force stringification
218 5         17 for (unpack "(A32)*", unpack "H*", $str) {
219 5         18 my @b = unpack "(A2)*", $_;
220 5         12 my $out = sprintf "%04x ", $off;
221 5   100     49 $out .= " ".($b[$_]||" ") for 0 .. 7;
222 5         4 $out .= " ";
223 5   100     51 $out .= " ".($b[$_]||" ") for 8 .. 15;
224 5         6 $out .= " ";
225 5 100 100     5 $out .= ($_ < 0x20 || $_ >= 0x7f ? "." : chr $_) for map { hex $_ } @b;
  45         112  
226 5         8 push @out, $out."\n";
227 5         9 $off += 16;
228             }
229              
230 5 50       10 wantarray and return @out;
231              
232 5 50       23 defined wantarray and return join "", @out;
233              
234 0         0 warn join "", @out;
235             } # DHexDump
236              
237             "Indent";
238              
239             __END__
240              
241             =head1 NAME
242              
243             Data::Peek - A collection of low-level debug facilities
244              
245             =head1 SYNOPSIS
246              
247             use Data::Peek;
248              
249             print DDumper \%hash; # Same syntax as Data::Dumper
250             DTidy { ref => $ref };
251              
252             print DPeek \$var;
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");
257              
258             my $dump = DDump $var;
259             my %hash = DDump \@list;
260             DDump \%hash;
261              
262             my %hash = DDump (\%hash, 5); # dig 5 levels deep
263              
264             my $dump;
265             open my $fh, ">", \$dump;
266             DDump_IO ($fh, \%hash, 6);
267             close $fh;
268             print $dump;
269              
270             # Imports
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");
274             DDsort ("R");
275             DDumper [ $x ]; # use of :tidy make DDumper behave as DTidy
276              
277             =head1 DESCRIPTION
278              
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.
283              
284             =head2 DDumper ($var, ...)
285              
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.
290              
291             $Data::Dumper::Sortkeys = 1;
292             $Data::Dumper::Indent = 1;
293              
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:
297              
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
302              
303             In void context, C<DDumper ()> warn ()'s.
304              
305             Example
306              
307             $ perl -MDP \
308             -e'DDumper { ape => 1, foo => "egg", bar => [ 2, "baz", undef ]};'
309              
310             { ape => 1,
311             bar => [
312             2,
313             'baz',
314             undef
315             ],
316             foo => 'egg'
317             };
318              
319             =head2 DTidy ($var, ...)
320              
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):
324              
325             $ perl -MDP=:tidy \
326             -we'DDumper { ape => 1, foo => "egg", bar => [ 2, "baz", undef ]};'
327             { 'ape' => 1,
328             'bar' => [2, 'baz', undef],
329             'foo' => 'egg'
330             }
331              
332             If C<Data::Peek> is C<use>d with import argument C<:tidy>, this is the
333             default output method for C<DDumper>.
334              
335             If L<Perl::Tidy> is not available, C<DTidy> will fallback to C<DDumper>.
336              
337             This idea was shamelessly copied from John McNamara's L<Data::Dumper::Perltidy>.
338              
339             =head2 DDsort ( 0 | 1 | R | V | VR | VN | VNR )
340              
341             Set the hash sort algorithm for DDumper. The default is to sort by key value.
342              
343             0 - Do not sort
344             1 - Sort by key
345             R - Reverse sort by key
346             V - Sort by value
347             VR - Reverse sort by value
348             VN - Sort by value numerical
349             VNR - Reverse sort by value numerical
350              
351             These can also be passed to import:
352              
353             $ perl -MDP=VNR \
354             -we'DDumper { foo => 1, bar => 2, zap => 3, gum => 13 }'
355             { gum => 13,
356             zap => 3,
357             bar => 2,
358             foo => 1
359             };
360             $ perl -MDP=V \
361             -we'DDumper { foo => 1, bar => 2, zap => 3, gum => 13 }'
362             { foo => 1,
363             gum => 13,
364             bar => 2,
365             zap => 3
366             };
367              
368             =head2 DPeek
369              
370             =head2 DPeek ($var)
371              
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 $_.
374              
375             Example
376              
377             print DPeek "abc\x{0a}de\x{20ac}fg";
378              
379             PV("abc\nde\342\202\254fg"\0) [UTF8 "abc\nde\x{20ac}fg"]
380              
381             In void context, C<DPeek ()> prints to C<STDERR> plus a newline.
382              
383             =head2 DDisplay
384              
385             =head2 DDisplay ($var)
386              
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
391             no have a valid PV.
392              
393             Example
394              
395             print DDisplay "abc\x{0a}de\x{20ac}fg";
396              
397             "abc\nde\x{20ac}fg"
398              
399             In void context, C<DDisplay ()> uses C<warn> to display the result.
400              
401             =head2 DHexDump
402              
403             =head2 DHexDump ($var)
404              
405             =head2 DHexDump ($var, $length)
406              
407             Show the (stringified) content of a scalar as a hex-dump. If C<$var>
408             is omitted, C<$_> is dumped. Returns C<undef> or an empty list if
409             C<$var> (or C<$_>) is undefined. If C<$length> is given and is lower than
410             the length of the stringified C<$var>, only <$length> bytes are dumped.
411              
412             In void context, the dump is done to STDERR. In scalar context, the
413             complete dump is returned as a single string. In list context, the dump
414             is returned as lines.
415              
416             Example
417              
418             print DHexDump "abc\x{0a}de\x{20ac}fg";
419              
420             0000 61 62 63 0a 64 65 e2 82 ac 66 67 abc.de...fg
421              
422             =head2 my ($pv, $iv, $nv, $rv, $hm) = DDual ($var [, $getmagic])
423              
424             DDual will return the basic elements in a variable, guaranteeing that no
425             conversion takes place. This is very useful for dual-var variables, or
426             when checking is a variable has defined entries for a certain type of
427             scalar. For each String (PV), Integer (IV), Double (NV), and Reference (RV),
428             the current value of C<$var> is returned or undef if it is not set (yet).
429             The 5th element is an indicator if C<$var> has magic, which is B<not> invoked
430             in the returned values, unless explicitly asked for with a true optional
431             second argument.
432              
433             Example
434              
435             print DPeek for DDual ($!, 1);
436              
437             In void context, DDual does the equivalent of
438              
439             { my @d = DDual ($!, 1);
440             print STDERR
441             DPeek ($!), "\n",
442             " PV: ", DPeek ($d[0]), "\n",
443             " IV: ", DPeek ($d[1]), "\n",
444             " NV: ", DPeek ($d[2]), "\n",
445             " RV: ", DPeek ($d[3]), "\n";
446             }
447            
448             =head2 my $len = DGrow ($pv, $size)
449              
450             Fastest way to preallocate space for a PV scalar. Returns the allocated
451             length. If $size is smaller than the already allocated space, it will
452             not shrink.
453              
454             cmpthese (-2, {
455             pack => q{my $x = ""; $x = pack "x20000"; $x = "";},
456             op_x => q{my $x = ""; $x = "x" x 20000; $x = "";},
457             grow => q{my $x = ""; DGrow ($x, 20000); $x = "";},
458             });
459              
460             Rate op_x pack grow 5.8.9 5.10.1 5.12.4 5.14.2
461             op_x 62127/s -- -59% -96% 118606/s 119730/s 352255/s 362605/s
462             pack 152046/s 145% -- -91% 380075/s 355666/s 347247/s 387349/s
463             grow 1622943/s 2512% 967% -- 2818380/s 2918783/s 2672340/s 2886787/s
464              
465             =head2 my $tp = triplevar ($pv, $iv, $nv)
466              
467             When making C<DDual ()> I wondered if it were possible to create triple-val
468             scalar variables. L<Scalar::Util> already gives us C<dualvar ()>, that creates
469             you a scalar with different numeric and string values that return different
470             values in different context. Not that C<triplevar ()> would be very useful,
471             compared to C<dualvar ()>, but at least this shows that it is possible.
472              
473             C<triplevar ()> is not exported by default.
474              
475             Example:
476              
477             print DPeek for DDual
478             Data::Peek::triplevar ("\N{GREEK SMALL LETTER PI}", 3, 3.1415);
479              
480             PV("\317\200"\0) [UTF8 "\x{3c0}"]
481             IV(3)
482             NV(3.1415)
483             SV_UNDEF
484             IV(0)
485              
486             =head2 DDump ($var [, $dig_level])
487              
488             A very useful module when debugging is C<Devel::Peek>, but is has one big
489             disadvantage: it only prints to STDERR, which is not very handy when your
490             code wants to inspect variables at a low level.
491              
492             Perl itself has C<sv_dump ()>, which does something similar, but still
493             prints to STDERR, and only one level deep.
494              
495             C<DDump ()> is an attempt to make the innards available to the script level
496             with a reasonable level of compatibility. C<DDump ()> is context sensitive.
497              
498             In void context, it behaves exactly like C<Perl_sv_dump ()>.
499              
500             In scalar context, it returns what C<Perl_sv_dump ()> would have printed.
501              
502             In list context, it returns a hash of the variable's properties. In this mode
503             you can pass an optional second argument that determines the depth of digging.
504              
505             Example
506              
507             print scalar DDump "abc\x{0a}de\x{20ac}fg"
508              
509             SV = PV(0x723250) at 0x8432b0
510             REFCNT = 1
511             FLAGS = (PADBUSY,PADMY,POK,pPOK,UTF8)
512             PV = 0x731ac0 "abc\nde\342\202\254fg"\0 [UTF8 "abc\nde\x{20ac}fg"]
513             CUR = 11
514             LEN = 16
515              
516             my %h = DDump "abc\x{0a}de\x{20ac}fg";
517             print DDumper \%h;
518              
519             { CUR => '11',
520             FLAGS => {
521             PADBUSY => 1,
522             PADMY => 1,
523             POK => 1,
524             UTF8 => 1,
525             pPOK => 1
526             },
527             LEN => '16',
528             PV => '0x731ac0 "abc\\nde\\342\\202\\254fg"\\0 [UTF8 "abc\\nde\\x{20ac}fg"]',
529             REFCNT => '1',
530             sv => 'PV(0x723250) at 0x8432c0'
531             };
532              
533             my %h = DDump {
534             ape => 1,
535             foo => "egg",
536             bar => [ 2, "baz", undef ],
537             }, 1;
538             print DDumper \%h;
539              
540             { FLAGS => {
541             PADBUSY => 1,
542             PADMY => 1,
543             ROK => 1
544             },
545             REFCNT => '1',
546             RV => {
547             PVIV("ape") => {
548             FLAGS => {
549             IOK => 1,
550             PADBUSY => 1,
551             PADMY => 1,
552             pIOK => 1
553             },
554             IV => '1',
555             REFCNT => '1',
556             sv => 'IV(0x747020) at 0x843a10'
557             },
558             PVIV("bar") => {
559             CUR => '0',
560             FLAGS => {
561             PADBUSY => 1,
562             PADMY => 1,
563             ROK => 1
564             },
565             IV => '1',
566             LEN => '0',
567             PV => '0x720210 ""',
568             REFCNT => '1',
569             RV => '0x720210',
570             sv => 'PVIV(0x7223e0) at 0x843a10'
571             },
572             PVIV("foo") => {
573             CUR => '3',
574             FLAGS => {
575             PADBUSY => 1,
576             PADMY => 1,
577             POK => 1,
578             pPOK => 1
579             },
580             IV => '1',
581             LEN => '8',
582             PV => '0x7496c0 "egg"\\0',
583             REFCNT => '1',
584             sv => 'PVIV(0x7223e0) at 0x843a10'
585             }
586             },
587             sv => 'RV(0x79d058) at 0x843310'
588             };
589              
590             =head2 DDump_IO ($io, $var [, $dig_level])
591              
592             A wrapper function around perl's internal C<Perl_do_sv_dump ()>, which
593             makes C<Devel::Peek> completely superfluous.
594              
595             Example
596              
597             my $dump;
598             open my $eh, ">", \$dump;
599             DDump_IO ($eh, { 3 => 4, ape => [5..8]}, 6);
600             close $eh;
601             print $dump;
602              
603             SV = RV(0x79d9e0) at 0x843f00
604             REFCNT = 1
605             FLAGS = (TEMP,ROK)
606             RV = 0x741090
607             SV = PVHV(0x79c948) at 0x741090
608             REFCNT = 1
609             FLAGS = (SHAREKEYS)
610             IV = 2
611             NV = 0
612             ARRAY = 0x748ff0 (0:7, 2:1)
613             hash quality = 62.5%
614             KEYS = 2
615             FILL = 1
616             MAX = 7
617             RITER = -1
618             EITER = 0x0
619             Elt "ape" HASH = 0x97623e03
620             SV = RV(0x79d9d8) at 0x8440e0
621             REFCNT = 1
622             FLAGS = (ROK)
623             RV = 0x741470
624             SV = PVAV(0x7264b0) at 0x741470
625             REFCNT = 2
626             FLAGS = ()
627             IV = 0
628             NV = 0
629             ARRAY = 0x822f70
630             FILL = 3
631             MAX = 3
632             ARYLEN = 0x0
633             FLAGS = (REAL)
634             Elt No. 0
635             SV = IV(0x7467c8) at 0x7c1aa0
636             REFCNT = 1
637             FLAGS = (IOK,pIOK)
638             IV = 5
639             Elt No. 1
640             SV = IV(0x7467b0) at 0x8440f0
641             REFCNT = 1
642             FLAGS = (IOK,pIOK)
643             IV = 6
644             Elt No. 2
645             SV = IV(0x746810) at 0x75be00
646             REFCNT = 1
647             FLAGS = (IOK,pIOK)
648             IV = 7
649             Elt No. 3
650             SV = IV(0x746d38) at 0x7799d0
651             REFCNT = 1
652             FLAGS = (IOK,pIOK)
653             IV = 8
654             Elt "3" HASH = 0xa400c7f3
655             SV = IV(0x746fd0) at 0x7200e0
656             REFCNT = 1
657             FLAGS = (IOK,pIOK)
658             IV = 4
659              
660             =head1 INTERNALS
661              
662             C<DDump ()> uses an XS wrapper around C<Perl_sv_dump ()> where the
663             STDERR is temporarily caught to a pipe. The internal XS helper functions
664             are not meant for user space
665              
666             =head2 DDump_XS (SV *sv)
667              
668             Base interface to internals for C<DDump ()>.
669              
670             =head1 BUGS
671              
672             Windows and AIX might be using a build where not all symbols that were
673             supposed to be exported in the public API are not. Perl_pv_peek () is
674             one of them.
675              
676             Not all types of references are supported.
677              
678             No idea how far back this goes in perl support, but Devel::PPPort has
679             proven to be a big help.
680              
681             =head1 SEE ALSO
682              
683             L<Devel::Peek>, L<Data::Dumper>, L<Data::Dump>, L<Devel::Dumpvar>,
684             L<Data::Dump::Streamer>, L<Data::Dumper::Perltidy>, L<Perl::Tidy>.
685              
686             =head1 AUTHOR
687              
688             H.Merijn Brand <h.m.brand@xs4all.nl>
689              
690             =head1 COPYRIGHT AND LICENSE
691              
692             Copyright (C) 2008-2016 H.Merijn Brand
693              
694             This library is free software; you can redistribute it and/or modify
695             it under the same terms as Perl itself.
696              
697             =cut