← Index
NYTProf Performance Profile   « line view »
For script/ponapi
  Run on Wed Feb 10 15:51:26 2016
Reported on Thu Feb 11 09:43:11 2016

Filename/usr/lib/perl/5.18/Data/Dumper.pm
StatementsExecuted 38 statements in 3.63ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11115µs161µsData::Dumper::::BEGIN@24Data::Dumper::BEGIN@24
11115µs56µsData::Dumper::::BEGIN@271Data::Dumper::BEGIN@271
11112µs15µsData::Dumper::::BEGIN@721Data::Dumper::BEGIN@721
1118µs46µsData::Dumper::::BEGIN@22Data::Dumper::BEGIN@22
1117µs7µsData::Dumper::::BEGIN@12Data::Dumper::BEGIN@12
1117µs7µsData::Dumper::::BEGIN@18Data::Dumper::BEGIN@18
1112µs2µsData::Dumper::::_vstringData::Dumper::_vstring (xsub)
0000s0sData::Dumper::::BlessData::Dumper::Bless
0000s0sData::Dumper::::DESTROYData::Dumper::DESTROY
0000s0sData::Dumper::::DeepcopyData::Dumper::Deepcopy
0000s0sData::Dumper::::DeparseData::Dumper::Deparse
0000s0sData::Dumper::::DumpData::Dumper::Dump
0000s0sData::Dumper::::DumperData::Dumper::Dumper
0000s0sData::Dumper::::DumperXData::Dumper::DumperX
0000s0sData::Dumper::::DumpperlData::Dumper::Dumpperl
0000s0sData::Dumper::::FreezerData::Dumper::Freezer
0000s0sData::Dumper::::IndentData::Dumper::Indent
0000s0sData::Dumper::::MaxdepthData::Dumper::Maxdepth
0000s0sData::Dumper::::NamesData::Dumper::Names
0000s0sData::Dumper::::PadData::Dumper::Pad
0000s0sData::Dumper::::PairData::Dumper::Pair
0000s0sData::Dumper::::PurityData::Dumper::Purity
0000s0sData::Dumper::::QuotekeysData::Dumper::Quotekeys
0000s0sData::Dumper::::ResetData::Dumper::Reset
0000s0sData::Dumper::::SeenData::Dumper::Seen
0000s0sData::Dumper::::SortkeysData::Dumper::Sortkeys
0000s0sData::Dumper::::SparseseenData::Dumper::Sparseseen
0000s0sData::Dumper::::TerseData::Dumper::Terse
0000s0sData::Dumper::::ToasterData::Dumper::Toaster
0000s0sData::Dumper::::UseperlData::Dumper::Useperl
0000s0sData::Dumper::::UseqqData::Dumper::Useqq
0000s0sData::Dumper::::ValuesData::Dumper::Values
0000s0sData::Dumper::::VarnameData::Dumper::Varname
0000s0sData::Dumper::::_compose_outData::Dumper::_compose_out
0000s0sData::Dumper::::_dumpData::Dumper::_dump
0000s0sData::Dumper::::_quoteData::Dumper::_quote
0000s0sData::Dumper::::_refine_nameData::Dumper::_refine_name
0000s0sData::Dumper::::_sortkeysData::Dumper::_sortkeys
0000s0sData::Dumper::::format_refaddrData::Dumper::format_refaddr
0000s0sData::Dumper::::init_refaddr_formatData::Dumper::init_refaddr_format
0000s0sData::Dumper::::newData::Dumper::new
0000s0sData::Dumper::::qquoteData::Dumper::qquote
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1#
2# Data/Dumper.pm
3#
4# convert perl data structures into perl syntax suitable for both printing
5# and eval
6#
7# Documentation at the __END__
8#
9
10package Data::Dumper;
11
12
# spent 7µs within Data::Dumper::BEGIN@12 which was called: # once (7µs+0s) by Devel::StackTrace::AsHTML::BEGIN@7 at line 14
BEGIN {
1315µs $VERSION = '2.145'; # Don't forget to set version and release
14117µs17µs} # date in POD below!
# spent 7µs making 1 call to Data::Dumper::BEGIN@12
15
16#$| = 1;
17
18242µs17µs
# spent 7µs within Data::Dumper::BEGIN@18 which was called: # once (7µs+0s) by Devel::StackTrace::AsHTML::BEGIN@7 at line 18
use 5.006_001;
# spent 7µs making 1 call to Data::Dumper::BEGIN@18
191900nsrequire Exporter;
201400nsrequire overload;
21
22268µs284µs
# spent 46µs (8+38) within Data::Dumper::BEGIN@22 which was called: # once (8µs+38µs) by Devel::StackTrace::AsHTML::BEGIN@7 at line 22
use Carp;
# spent 46µs making 1 call to Data::Dumper::BEGIN@22 # spent 38µs making 1 call to Exporter::import
23
24
# spent 161µs (15+146) within Data::Dumper::BEGIN@24 which was called: # once (15µs+146µs) by Devel::StackTrace::AsHTML::BEGIN@7 at line 38
BEGIN {
2515µs @ISA = qw(Exporter);
261400ns @EXPORT = qw(Dumper);
271200ns @EXPORT_OK = qw(DumperX);
28
29 # if run under miniperl, or otherwise lacking dynamic loading,
30 # XSLoader should be attempted to load, or the pure perl flag
31 # toggled on load failure.
3213µs eval {
331600ns require XSLoader;
341152µs1146µs XSLoader::load( 'Data::Dumper' );
# spent 146µs making 1 call to XSLoader::load
351500ns 1
36 }
37 or $Useperl = 1;
381821µs1161µs}
# spent 161µs making 1 call to Data::Dumper::BEGIN@24
39
40# module vars and their defaults
411600ns$Indent = 2 unless defined $Indent;
421100ns$Purity = 0 unless defined $Purity;
431500ns$Pad = "" unless defined $Pad;
441300ns$Varname = "VAR" unless defined $Varname;
451100ns$Useqq = 0 unless defined $Useqq;
461200ns$Terse = 0 unless defined $Terse;
471300ns$Freezer = "" unless defined $Freezer;
481200ns$Toaster = "" unless defined $Toaster;
491100ns$Deepcopy = 0 unless defined $Deepcopy;
501100ns$Quotekeys = 1 unless defined $Quotekeys;
511200ns$Bless = "bless" unless defined $Bless;
52#$Expdepth = 0 unless defined $Expdepth;
531200ns$Maxdepth = 0 unless defined $Maxdepth;
541200ns$Pair = ' => ' unless defined $Pair;
551100ns$Useperl = 0 unless defined $Useperl;
561100ns$Sortkeys = 0 unless defined $Sortkeys;
571100ns$Deparse = 0 unless defined $Deparse;
581100ns$Sparseseen = 0 unless defined $Sparseseen;
59
60#
61# expects an arrayref of values to be dumped.
62# can optionally pass an arrayref of names for the values.
63# names must have leading $ sign stripped. begin the name with *
64# to cause output of arrays and hashes rather than refs.
65#
66sub new {
67 my($c, $v, $n) = @_;
68
69 croak "Usage: PACKAGE->new(ARRAYREF, [ARRAYREF])"
70 unless (defined($v) && (ref($v) eq 'ARRAY'));
71 $n = [] unless (defined($n) && (ref($n) eq 'ARRAY'));
72
73 my($s) = {
74 level => 0, # current recursive depth
75 indent => $Indent, # various styles of indenting
76 pad => $Pad, # all lines prefixed by this string
77 xpad => "", # padding-per-level
78 apad => "", # added padding for hash keys n such
79 sep => "", # list separator
80 pair => $Pair, # hash key/value separator: defaults to ' => '
81 seen => {}, # local (nested) refs (id => [name, val])
82 todump => $v, # values to dump []
83 names => $n, # optional names for values []
84 varname => $Varname, # prefix to use for tagging nameless ones
85 purity => $Purity, # degree to which output is evalable
86 useqq => $Useqq, # use "" for strings (backslashitis ensues)
87 terse => $Terse, # avoid name output (where feasible)
88 freezer => $Freezer, # name of Freezer method for objects
89 toaster => $Toaster, # name of method to revive objects
90 deepcopy => $Deepcopy, # dont cross-ref, except to stop recursion
91 quotekeys => $Quotekeys, # quote hash keys
92 'bless' => $Bless, # keyword to use for "bless"
93# expdepth => $Expdepth, # cutoff depth for explicit dumping
94 maxdepth => $Maxdepth, # depth beyond which we give up
95 useperl => $Useperl, # use the pure Perl implementation
96 sortkeys => $Sortkeys, # flag or filter for sorting hash keys
97 deparse => $Deparse, # use B::Deparse for coderefs
98 noseen => $Sparseseen, # do not populate the seen hash unless necessary
99 };
100
101 if ($Indent > 0) {
102 $s->{xpad} = " ";
103 $s->{sep} = "\n";
104 }
105 return bless($s, $c);
106}
107
108# Packed numeric addresses take less memory. Plus pack is faster than sprintf
109
110# Most users of current versions of Data::Dumper will be 5.008 or later.
111# Anyone on 5.6.1 and 5.6.2 upgrading will be rare (particularly judging by
112# the bug reports from users on those platforms), so for the common case avoid
113# complexity, and avoid even compiling the unneeded code.
114
115sub init_refaddr_format {
116}
117
118sub format_refaddr {
119 require Scalar::Util;
120 pack "J", Scalar::Util::refaddr(shift);
121};
122
12311µsif ($] < 5.008) {
124 eval <<'EOC' or die;
125 no warnings 'redefine';
126 my $refaddr_format;
127 sub init_refaddr_format {
128 require Config;
129 my $f = $Config::Config{uvxformat};
130 $f =~ tr/"//d;
131 $refaddr_format = "0x%" . $f;
132 }
133
134 sub format_refaddr {
135 require Scalar::Util;
136 sprintf $refaddr_format, Scalar::Util::refaddr(shift);
137 }
138
139 1
140EOC
141}
142
143#
144# add-to or query the table of already seen references
145#
146sub Seen {
147 my($s, $g) = @_;
148 if (defined($g) && (ref($g) eq 'HASH')) {
149 init_refaddr_format();
150 my($k, $v, $id);
151 while (($k, $v) = each %$g) {
152 if (defined $v) {
153 if (ref $v) {
154 $id = format_refaddr($v);
155 if ($k =~ /^[*](.*)$/) {
156 $k = (ref $v eq 'ARRAY') ? ( "\\\@" . $1 ) :
157 (ref $v eq 'HASH') ? ( "\\\%" . $1 ) :
158 (ref $v eq 'CODE') ? ( "\\\&" . $1 ) :
159 ( "\$" . $1 ) ;
160 }
161 elsif ($k !~ /^\$/) {
162 $k = "\$" . $k;
163 }
164 $s->{seen}{$id} = [$k, $v];
165 }
166 else {
167 carp "Only refs supported, ignoring non-ref item \$$k";
168 }
169 }
170 else {
171 carp "Value of ref must be defined; ignoring undefined item \$$k";
172 }
173 }
174 return $s;
175 }
176 else {
177 return map { @$_ } values %{$s->{seen}};
178 }
179}
180
181#
182# set or query the values to be dumped
183#
184sub Values {
185 my($s, $v) = @_;
186 if (defined($v)) {
187 if (ref($v) eq 'ARRAY') {
188 $s->{todump} = [@$v]; # make a copy
189 return $s;
190 }
191 else {
192 croak "Argument to Values, if provided, must be array ref";
193 }
194 }
195 else {
196 return @{$s->{todump}};
197 }
198}
199
200#
201# set or query the names of the values to be dumped
202#
203sub Names {
204 my($s, $n) = @_;
205 if (defined($n)) {
206 if (ref($n) eq 'ARRAY') {
207 $s->{names} = [@$n]; # make a copy
208 return $s;
209 }
210 else {
211 croak "Argument to Names, if provided, must be array ref";
212 }
213 }
214 else {
215 return @{$s->{names}};
216 }
217}
218
219sub DESTROY {}
220
221sub Dump {
222 return &Dumpxs
223 unless $Data::Dumper::Useperl || (ref($_[0]) && $_[0]->{useperl}) ||
224 $Data::Dumper::Useqq || (ref($_[0]) && $_[0]->{useqq}) ||
225 $Data::Dumper::Deparse || (ref($_[0]) && $_[0]->{deparse});
226 return &Dumpperl;
227}
228
229#
230# dump the refs in the current dumper object.
231# expects same args as new() if called via package name.
232#
233sub Dumpperl {
234 my($s) = shift;
235 my(@out, $val, $name);
236 my($i) = 0;
237 local(@post);
238 init_refaddr_format();
239
240 $s = $s->new(@_) unless ref $s;
241
242 for $val (@{$s->{todump}}) {
243 @post = ();
244 $name = $s->{names}[$i++];
245 $name = $s->_refine_name($name, $val, $i);
246
247 my $valstr;
248 {
249 local($s->{apad}) = $s->{apad};
250 $s->{apad} .= ' ' x (length($name) + 3) if $s->{indent} >= 2 and !$s->{terse};
251 $valstr = $s->_dump($val, $name);
252 }
253
254 $valstr = "$name = " . $valstr . ';' if @post or !$s->{terse};
255 my $out = $s->_compose_out($valstr, \@post);
256
257 push @out, $out;
258 }
259 return wantarray ? @out : join('', @out);
260}
261
262# wrap string in single quotes (escaping if needed)
263sub _quote {
264 my $val = shift;
265 $val =~ s/([\\\'])/\\$1/g;
266 return "'" . $val . "'";
267}
268
269# Old Perls (5.14-) have trouble resetting vstring magic when it is no
270# longer valid.
27121.97ms398µs
# spent 56µs (15+42) within Data::Dumper::BEGIN@271 which was called: # once (15µs+42µs) by Devel::StackTrace::AsHTML::BEGIN@7 at line 271
use constant _bad_vsmg => defined &_vstring && (_vstring(~v0)||'') eq "v0";
# spent 56µs making 1 call to Data::Dumper::BEGIN@271 # spent 40µs making 1 call to constant::import # spent 2µs making 1 call to Data::Dumper::_vstring
272
273#
274# twist, toil and turn;
275# and recurse, of course.
276# sometimes sordidly;
277# and curse if no recourse.
278#
279sub _dump {
280 my($s, $val, $name) = @_;
281 my($out, $type, $id, $sname);
282
283 $type = ref $val;
284 $out = "";
285
286 if ($type) {
287
288 # Call the freezer method if it's specified and the object has the
289 # method. Trap errors and warn() instead of die()ing, like the XS
290 # implementation.
291 my $freezer = $s->{freezer};
292 if ($freezer and UNIVERSAL::can($val, $freezer)) {
293 eval { $val->$freezer() };
294 warn "WARNING(Freezer method call failed): $@" if $@;
295 }
296
297 require Scalar::Util;
298 my $realpack = Scalar::Util::blessed($val);
299 my $realtype = $realpack ? Scalar::Util::reftype($val) : ref $val;
300 $id = format_refaddr($val);
301
302 # Note: By this point $name is always defined and of non-zero length.
303 # Keep a tab on it so that we dont fall into recursive pit.
304 if (exists $s->{seen}{$id}) {
305 if ($s->{purity} and $s->{level} > 0) {
306 $out = ($realtype eq 'HASH') ? '{}' :
307 ($realtype eq 'ARRAY') ? '[]' :
308 'do{my $o}' ;
309 push @post, $name . " = " . $s->{seen}{$id}[0];
310 }
311 else {
312 $out = $s->{seen}{$id}[0];
313 if ($name =~ /^([\@\%])/) {
314 my $start = $1;
315 if ($out =~ /^\\$start/) {
316 $out = substr($out, 1);
317 }
318 else {
319 $out = $start . '{' . $out . '}';
320 }
321 }
322 }
323 return $out;
324 }
325 else {
326 # store our name
327 $s->{seen}{$id} = [ (
328 ($name =~ /^[@%]/)
329 ? ('\\' . $name )
330 : ($realtype eq 'CODE' and $name =~ /^[*](.*)$/)
331 ? ('\\&' . $1 )
332 : $name
333 ), $val ];
334 }
335 my $no_bless = 0;
336 my $is_regex = 0;
337 if ( $realpack and ($] >= 5.009005 ? re::is_regexp($val) : $realpack eq 'Regexp') ) {
338 $is_regex = 1;
339 $no_bless = $realpack eq 'Regexp';
340 }
341
342 # If purity is not set and maxdepth is set, then check depth:
343 # if we have reached maximum depth, return the string
344 # representation of the thing we are currently examining
345 # at this depth (i.e., 'Foo=ARRAY(0xdeadbeef)').
346 if (!$s->{purity}
347 and defined($s->{maxdepth})
348 and $s->{maxdepth} > 0
349 and $s->{level} >= $s->{maxdepth})
350 {
351 return qq['$val'];
352 }
353
354 # we have a blessed ref
355 my ($blesspad);
356 if ($realpack and !$no_bless) {
357 $out = $s->{'bless'} . '( ';
358 $blesspad = $s->{apad};
359 $s->{apad} .= ' ' if ($s->{indent} >= 2);
360 }
361
362 $s->{level}++;
363 my $ipad = $s->{xpad} x $s->{level};
364
365 if ($is_regex) {
366 my $pat;
367 # This really sucks, re:regexp_pattern is in ext/re/re.xs and not in
368 # universal.c, and even worse we cant just require that re to be loaded
369 # we *have* to use() it.
370 # We should probably move it to universal.c for 5.10.1 and fix this.
371 # Currently we only use re::regexp_pattern when the re is blessed into another
372 # package. This has the disadvantage of meaning that a DD dump won't round trip
373 # as the pattern will be repeatedly wrapped with the same modifiers.
374 # This is an aesthetic issue so we will leave it for now, but we could use
375 # regexp_pattern() in list context to get the modifiers separately.
376 # But since this means loading the full debugging engine in process we wont
377 # bother unless its necessary for accuracy.
378 if (($realpack ne 'Regexp') && defined(*re::regexp_pattern{CODE})) {
379 $pat = re::regexp_pattern($val);
380 }
381 else {
382 $pat = "$val";
383 }
384 $pat =~ s <(\\.)|/> { $1 || '\\/' }ge;
385 $out .= "qr/$pat/";
386 }
387 elsif ($realtype eq 'SCALAR' || $realtype eq 'REF'
388 || $realtype eq 'VSTRING') {
389 if ($realpack) {
390 $out .= 'do{\\(my $o = ' . $s->_dump($$val, "\${$name}") . ')}';
391 }
392 else {
393 $out .= '\\' . $s->_dump($$val, "\${$name}");
394 }
395 }
396 elsif ($realtype eq 'GLOB') {
397 $out .= '\\' . $s->_dump($$val, "*{$name}");
398 }
399 elsif ($realtype eq 'ARRAY') {
400 my($pad, $mname);
401 my($i) = 0;
402 $out .= ($name =~ /^\@/) ? '(' : '[';
403 $pad = $s->{sep} . $s->{pad} . $s->{apad};
404 ($name =~ /^\@(.*)$/) ? ($mname = "\$" . $1) :
405 # omit -> if $foo->[0]->{bar}, but not ${$foo->[0]}->{bar}
406 ($name =~ /^\\?[\%\@\*\$][^{].*[]}]$/) ? ($mname = $name) :
407 ($mname = $name . '->');
408 $mname .= '->' if $mname =~ /^\*.+\{[A-Z]+\}$/;
409 for my $v (@$val) {
410 $sname = $mname . '[' . $i . ']';
411 $out .= $pad . $ipad . '#' . $i
412 if $s->{indent} >= 3;
413 $out .= $pad . $ipad . $s->_dump($v, $sname);
414 $out .= "," if $i++ < $#$val;
415 }
416 $out .= $pad . ($s->{xpad} x ($s->{level} - 1)) if $i;
417 $out .= ($name =~ /^\@/) ? ')' : ']';
418 }
419 elsif ($realtype eq 'HASH') {
420 my ($k, $v, $pad, $lpad, $mname, $pair);
421 $out .= ($name =~ /^\%/) ? '(' : '{';
422 $pad = $s->{sep} . $s->{pad} . $s->{apad};
423 $lpad = $s->{apad};
424 $pair = $s->{pair};
425 ($name =~ /^\%(.*)$/) ? ($mname = "\$" . $1) :
426 # omit -> if $foo->[0]->{bar}, but not ${$foo->[0]}->{bar}
427 ($name =~ /^\\?[\%\@\*\$][^{].*[]}]$/) ? ($mname = $name) :
428 ($mname = $name . '->');
429 $mname .= '->' if $mname =~ /^\*.+\{[A-Z]+\}$/;
430 my $sortkeys = defined($s->{sortkeys}) ? $s->{sortkeys} : '';
431 my $keys = [];
432 if ($sortkeys) {
433 if (ref($s->{sortkeys}) eq 'CODE') {
434 $keys = $s->{sortkeys}($val);
435 unless (ref($keys) eq 'ARRAY') {
436 carp "Sortkeys subroutine did not return ARRAYREF";
437 $keys = [];
438 }
439 }
440 else {
441 $keys = [ sort keys %$val ];
442 }
443 }
444
445 # Ensure hash iterator is reset
446 keys(%$val);
447
448 my $key;
449 while (($k, $v) = ! $sortkeys ? (each %$val) :
450 @$keys ? ($key = shift(@$keys), $val->{$key}) :
451 () )
452 {
453 my $nk = $s->_dump($k, "");
454 $nk = $1
455 if !$s->{quotekeys} and $nk =~ /^[\"\']([A-Za-z_]\w*)[\"\']$/;
456 $sname = $mname . '{' . $nk . '}';
457 $out .= $pad . $ipad . $nk . $pair;
458
459 # temporarily alter apad
460 $s->{apad} .= (" " x (length($nk) + 4))
461 if $s->{indent} >= 2;
462 $out .= $s->_dump($val->{$k}, $sname) . ",";
463 $s->{apad} = $lpad
464 if $s->{indent} >= 2;
465 }
466 if (substr($out, -1) eq ',') {
467 chop $out;
468 $out .= $pad . ($s->{xpad} x ($s->{level} - 1));
469 }
470 $out .= ($name =~ /^\%/) ? ')' : '}';
471 }
472 elsif ($realtype eq 'CODE') {
473 if ($s->{deparse}) {
474 require B::Deparse;
475 my $sub = 'sub ' . (B::Deparse->new)->coderef2text($val);
476 $pad = $s->{sep} . $s->{pad} . $s->{apad} . $s->{xpad} x ($s->{level} - 1);
477 $sub =~ s/\n/$pad/gse;
478 $out .= $sub;
479 }
480 else {
481 $out .= 'sub { "DUMMY" }';
482 carp "Encountered CODE ref, using dummy placeholder" if $s->{purity};
483 }
484 }
485 else {
486 croak "Can't handle '$realtype' type";
487 }
488
489 if ($realpack and !$no_bless) { # we have a blessed ref
490 $out .= ', ' . _quote($realpack) . ' )';
491 $out .= '->' . $s->{toaster} . '()'
492 if $s->{toaster} ne '';
493 $s->{apad} = $blesspad;
494 }
495 $s->{level}--;
496 }
497 else { # simple scalar
498
499 my $ref = \$_[1];
500 my $v;
501 # first, catalog the scalar
502 if ($name ne '') {
503 $id = format_refaddr($ref);
504 if (exists $s->{seen}{$id}) {
505 if ($s->{seen}{$id}[2]) {
506 $out = $s->{seen}{$id}[0];
507 #warn "[<$out]\n";
508 return "\${$out}";
509 }
510 }
511 else {
512 #warn "[>\\$name]\n";
513 $s->{seen}{$id} = ["\\$name", $ref];
514 }
515 }
516 $ref = \$val;
517 if (ref($ref) eq 'GLOB') { # glob
518 my $name = substr($val, 1);
519 if ($name =~ /^[A-Za-z_][\w:]*$/ && $name ne 'main::') {
520 $name =~ s/^main::/::/;
521 $sname = $name;
522 }
523 else {
524 $sname = $s->_dump(
525 $name eq 'main::' || $] < 5.007 && $name eq "main::\0"
526 ? ''
527 : $name,
528 "",
529 );
530 $sname = '{' . $sname . '}';
531 }
532 if ($s->{purity}) {
533 my $k;
534 local ($s->{level}) = 0;
535 for $k (qw(SCALAR ARRAY HASH)) {
536 my $gval = *$val{$k};
537 next unless defined $gval;
538 next if $k eq "SCALAR" && ! defined $$gval; # always there
539
540 # _dump can push into @post, so we hold our place using $postlen
541 my $postlen = scalar @post;
542 $post[$postlen] = "\*$sname = ";
543 local ($s->{apad}) = " " x length($post[$postlen]) if $s->{indent} >= 2;
544 $post[$postlen] .= $s->_dump($gval, "\*$sname\{$k\}");
545 }
546 }
547 $out .= '*' . $sname;
548 }
549 elsif (!defined($val)) {
550 $out .= "undef";
551 }
552 elsif (defined &_vstring and $v = _vstring($val)
553 and !_bad_vsmg || eval $v eq $val) {
554 $out .= $v;
555 }
556 elsif (!defined &_vstring
557 and ref $ref eq 'VSTRING' || eval{Scalar::Util::isvstring($val)}) {
558 $out .= sprintf "%vd", $val;
559 }
560 elsif ($val =~ /^(?:0|-?[1-9]\d{0,8})\z/) { # safe decimal number
561 $out .= $val;
562 }
563 else { # string
564 if ($s->{useqq} or $val =~ tr/\0-\377//c) {
565 # Fall back to qq if there's Unicode
566 $out .= qquote($val, $s->{useqq});
567 }
568 else {
569 $out .= _quote($val);
570 }
571 }
572 }
573 if ($id) {
574 # if we made it this far, $id was added to seen list at current
575 # level, so remove it to get deep copies
576 if ($s->{deepcopy}) {
577 delete($s->{seen}{$id});
578 }
579 elsif ($name) {
580 $s->{seen}{$id}[2] = 1;
581 }
582 }
583 return $out;
584}
585
586#
587# non-OO style of earlier version
588#
589sub Dumper {
590 return Data::Dumper->Dump([@_]);
591}
592
593# compat stub
594sub DumperX {
595 return Data::Dumper->Dumpxs([@_], []);
596}
597
598#
599# reset the "seen" cache
600#
601sub Reset {
602 my($s) = shift;
603 $s->{seen} = {};
604 return $s;
605}
606
607sub Indent {
608 my($s, $v) = @_;
609 if (defined($v)) {
610 if ($v == 0) {
611 $s->{xpad} = "";
612 $s->{sep} = "";
613 }
614 else {
615 $s->{xpad} = " ";
616 $s->{sep} = "\n";
617 }
618 $s->{indent} = $v;
619 return $s;
620 }
621 else {
622 return $s->{indent};
623 }
624}
625
626sub Pair {
627 my($s, $v) = @_;
628 defined($v) ? (($s->{pair} = $v), return $s) : $s->{pair};
629}
630
631sub Pad {
632 my($s, $v) = @_;
633 defined($v) ? (($s->{pad} = $v), return $s) : $s->{pad};
634}
635
636sub Varname {
637 my($s, $v) = @_;
638 defined($v) ? (($s->{varname} = $v), return $s) : $s->{varname};
639}
640
641sub Purity {
642 my($s, $v) = @_;
643 defined($v) ? (($s->{purity} = $v), return $s) : $s->{purity};
644}
645
646sub Useqq {
647 my($s, $v) = @_;
648 defined($v) ? (($s->{useqq} = $v), return $s) : $s->{useqq};
649}
650
651sub Terse {
652 my($s, $v) = @_;
653 defined($v) ? (($s->{terse} = $v), return $s) : $s->{terse};
654}
655
656sub Freezer {
657 my($s, $v) = @_;
658 defined($v) ? (($s->{freezer} = $v), return $s) : $s->{freezer};
659}
660
661sub Toaster {
662 my($s, $v) = @_;
663 defined($v) ? (($s->{toaster} = $v), return $s) : $s->{toaster};
664}
665
666sub Deepcopy {
667 my($s, $v) = @_;
668 defined($v) ? (($s->{deepcopy} = $v), return $s) : $s->{deepcopy};
669}
670
671sub Quotekeys {
672 my($s, $v) = @_;
673 defined($v) ? (($s->{quotekeys} = $v), return $s) : $s->{quotekeys};
674}
675
676sub Bless {
677 my($s, $v) = @_;
678 defined($v) ? (($s->{'bless'} = $v), return $s) : $s->{'bless'};
679}
680
681sub Maxdepth {
682 my($s, $v) = @_;
683 defined($v) ? (($s->{'maxdepth'} = $v), return $s) : $s->{'maxdepth'};
684}
685
686sub Useperl {
687 my($s, $v) = @_;
688 defined($v) ? (($s->{'useperl'} = $v), return $s) : $s->{'useperl'};
689}
690
691sub Sortkeys {
692 my($s, $v) = @_;
693 defined($v) ? (($s->{'sortkeys'} = $v), return $s) : $s->{'sortkeys'};
694}
695
696sub Deparse {
697 my($s, $v) = @_;
698 defined($v) ? (($s->{'deparse'} = $v), return $s) : $s->{'deparse'};
699}
700
701sub Sparseseen {
702 my($s, $v) = @_;
703 defined($v) ? (($s->{'noseen'} = $v), return $s) : $s->{'noseen'};
704}
705
706# used by qquote below
70714µsmy %esc = (
708 "\a" => "\\a",
709 "\b" => "\\b",
710 "\t" => "\\t",
711 "\n" => "\\n",
712 "\f" => "\\f",
713 "\r" => "\\r",
714 "\e" => "\\e",
715);
716
717# put a string value in double quotes
718sub qquote {
719 local($_) = shift;
720 s/([\\\"\@\$])/\\$1/g;
7212526µs218µs
# spent 15µs (12+3) within Data::Dumper::BEGIN@721 which was called: # once (12µs+3µs) by Devel::StackTrace::AsHTML::BEGIN@7 at line 721
my $bytes; { use bytes; $bytes = length }
# spent 15µs making 1 call to Data::Dumper::BEGIN@721 # spent 3µs making 1 call to bytes::import
722 s/([^\x00-\x7f])/'\x{'.sprintf("%x",ord($1)).'}'/ge if $bytes > length;
723 return qq("$_") unless
724 /[^ !"\#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~]/; # fast exit
725
726 my $high = shift || "";
727 s/([\a\b\t\n\f\r\e])/$esc{$1}/g;
728
729 if (ord('^')==94) { # ascii
730 # no need for 3 digits in escape for these
731 s/([\0-\037])(?!\d)/'\\'.sprintf('%o',ord($1))/eg;
732 s/([\0-\037\177])/'\\'.sprintf('%03o',ord($1))/eg;
733 # all but last branch below not supported --BEHAVIOR SUBJECT TO CHANGE--
734 if ($high eq "iso8859") {
735 s/([\200-\240])/'\\'.sprintf('%o',ord($1))/eg;
736 } elsif ($high eq "utf8") {
737# use utf8;
738# $str =~ s/([^\040-\176])/sprintf "\\x{%04x}", ord($1)/ge;
739 } elsif ($high eq "8bit") {
740 # leave it as it is
741 } else {
742 s/([\200-\377])/'\\'.sprintf('%03o',ord($1))/eg;
743 s/([^\040-\176])/sprintf "\\x{%04x}", ord($1)/ge;
744 }
745 }
746 else { # ebcdic
747 s{([^ !"\#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~])(?!\d)}
748 {my $v = ord($1); '\\'.sprintf(($v <= 037 ? '%o' : '%03o'), $v)}eg;
749 s{([^ !"\#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~])}
750 {'\\'.sprintf('%03o',ord($1))}eg;
751 }
752
753 return qq("$_");
754}
755
756# helper sub to sort hash keys in Perl < 5.8.0 where we don't have
757# access to sortsv() from XS
758sub _sortkeys { [ sort keys %{$_[0]} ] }
759
760sub _refine_name {
761 my $s = shift;
762 my ($name, $val, $i) = @_;
763 if (defined $name) {
764 if ($name =~ /^[*](.*)$/) {
765 if (defined $val) {
766 $name = (ref $val eq 'ARRAY') ? ( "\@" . $1 ) :
767 (ref $val eq 'HASH') ? ( "\%" . $1 ) :
768 (ref $val eq 'CODE') ? ( "\*" . $1 ) :
769 ( "\$" . $1 ) ;
770 }
771 else {
772 $name = "\$" . $1;
773 }
774 }
775 elsif ($name !~ /^\$/) {
776 $name = "\$" . $name;
777 }
778 }
779 else { # no names provided
780 $name = "\$" . $s->{varname} . $i;
781 }
782 return $name;
783}
784
785sub _compose_out {
786 my $s = shift;
787 my ($valstr, $postref) = @_;
788 my $out = "";
789 $out .= $s->{pad} . $valstr . $s->{sep};
790 if (@{$postref}) {
791 $out .= $s->{pad} .
792 join(';' . $s->{sep} . $s->{pad}, @{$postref}) .
793 ';' .
794 $s->{sep};
795 }
796 return $out;
797}
798
79918µs1;
800__END__
 
# spent 2µs within Data::Dumper::_vstring which was called: # once (2µs+0s) by Data::Dumper::BEGIN@271 at line 271
sub Data::Dumper::_vstring; # xsub