File Coverage

blib/lib/Data/Dumper/Interp.pm
Criterion Covered Total %
statement 544 685 79.4
branch 223 418 53.3
condition 68 106 64.1
subroutine 91 116 78.4
pod 18 30 60.0
total 944 1355 69.6


line stmt bran cond sub pod time code
1             # License: Public Domain or CC0
2             # See https://creativecommons.org/publicdomain/zero/1.0/
3             # The author, Jim Avera (jim.avera at gmail) has waived all copyright and
4             # related or neighboring rights. Attribution is requested but is not required.
5              
6             ##FIXME: Refaddr(1) has no effect inside Blessed structures
7              
8 9     9   96540 use strict; use warnings FATAL => 'all'; use utf8;
  9     9   61  
  9     9   290  
  9         49  
  9         15  
  9         309  
  9         5343  
  9         132  
  9         48  
9             #use 5.010; # say, state
10             #use 5.011; # cpantester gets warning that 5.11 is the minimum acceptable
11             #use 5.014; # /r for non-destructive substitution
12 9     9   404 use 5.018; # lexical_subs
  9         31  
13 9     9   46 use feature qw(say state lexical_subs current_sub);
  9         15  
  9         871  
14 9     9   61 use feature 'lexical_subs';
  9         15  
  9         242  
15              
16 9     9   61 no warnings "experimental::lexical_subs";
  9         27  
  9         672  
17              
18             package Data::Dumper::Interp;
19 9     9   59 { no strict 'refs'; ${__PACKAGE__."::VER"."SION"} = 997.999; }
  9         17  
  9         1554  
20             our $VERSION = '6.007'; # VERSION from Dist::Zilla::Plugin::OurPkgVersion
21             our $DATE = '2023-09-18'; # DATE from Dist::Zilla::Plugin::OurDate
22              
23             package
24             # newline so Dist::Zilla::Plugin::PkgVersion won't add $VERSION
25             DB {
26             sub DB_Vis_Evalwrapper {
27 1670     1670 0 278699 eval $Data::Dumper::Interp::string_to_eval; ## no critic
28             }
29             }
30              
31             package Data::Dumper::Interp;
32              
33 9     9   5448 use Moose;
  9         4238289  
  9         60  
34              
35             extends 'Data::Visitor' => { -version => 0.32 },
36             'Exporter' => { -version => 5.57 },
37             ;
38              
39 9     9   69497 no warnings "experimental::lexical_subs"; # un-do Moose forcing these on!!
  9         23  
  9         437  
40              
41 9     9   7287 use Data::Dumper ();
  9         65424  
  9         303  
42 9     9   70 use Carp;
  9         23  
  9         744  
43 9     9   4708 use POSIX qw(INT_MAX);
  9         60573  
  9         55  
44 9     9   13498 use Scalar::Util qw(blessed reftype refaddr looks_like_number weaken);
  9         24  
  9         742  
45 9     9   70 use List::Util 1.45 qw(min max first none all any sum0);
  9         191  
  9         851  
46 9     9   4639 use Data::Structure::Util qw/circular_off/;
  9         65491  
  9         642  
47 9     9   4832 use Regexp::Common qw/RE_balanced/;
  9         25539  
  9         39  
48 9     9   1451384 use Term::ReadKey ();
  9         19293  
  9         247  
49 9     9   67 use overload ();
  9         34  
  9         12707  
50              
51             ############################ Exports #######################################
52             # Short-hand functions/methods are generated on demand (i.e. if imported or
53             # called as a method) based on a naming convention.
54             ############################################################################
55              
56             our @EXPORT = qw( visnew
57             vis avis hvis ivis dvis
58             viso aviso hviso iviso dviso
59             visq avisq hvisq ivisq dvisq
60             visr avisr hvisr ivisr dvisr
61             rvis rvisq
62             addrvis addrvisl
63             u quotekey qsh qshlist qshpath
64             );
65              
66             our @EXPORT_OK = qw(addrvis_digits
67              
68             $Debug $MaxStringwidth $Truncsuffix $Objects $Foldwidth
69             $Useqq $Quotekeys $Sortkeys
70             $Maxdepth $Maxrecurse $Deparse $Deepcopy);
71              
72             our %EXPORT_TAGS = (
73             null => [],
74             );
75              
76             sub _generate_sub($;$); # forward
77              
78             #---------------------------------------------------------------------------
79             my $sane_cW = $^W;
80             my $sane_cH = $^H;
81             our @save_stack;
82             sub _SaveAndResetPunct() {
83             # Save things which will later be restored
84 7335     7335   74293 push @save_stack, [ $@, $!+0, $^E+0, $,, $/, $\, $?, $^W ];
85             # Reset sane values
86 7335         16222 $, = ""; # output field separator is null string
87 7335         17337 $/ = "\n"; # input record separator is newline
88 7335         14801 $\ = ""; # output record separator is null string
89 7335         13231 $? = 0; # child process exit status
90 7335         16231 $^W = $sane_cW; # our load-time warnings
91             #$^H = $sane_cH; # our load-time pragmas (strict etc.)
92             }
93             sub _RestorePunct_NoPop() {
94 9005     9005   14709 ( $@, $!, $^E, $,, $/, $\, $?, $^W ) = @{ $save_stack[-1] };
  9005         89224  
95             }
96             sub _RestorePunct() {
97 7335     7335   17161 &_RestorePunct_NoPop;
98 7335         16287 pop @save_stack;
99             }
100             #---------------------------------------------------------------------------
101              
102             our $AUTOLOAD_debug;
103              
104             sub import {
105 9     9   3250658 my $class = shift;
106 9         39 my @args = @_;
107              
108 9   100     61 my $exporting_default = (@args==0 or grep{ /:DEFAULT/ } @args);
109              
110 9         26 our $Debug;
111 9         26 local $Debug = $Debug;
112 9 50   6   99 if (my $tag = first{ /^:debug/i } @args) {
  6         26  
113 0         0 @args = grep{ ! /^:debug/i } @args;
  0         0  
114 0 0       0 my $level = ($tag =~ /=(\d+)/ ? $1 : 1);
115 0         0 $AUTOLOAD_debug = $Debug = $level; # show generated code
116             }
117              
118 9 100       56 if (grep{ /^:all$/i } @args) {
  6         28  
119 2         5 @args = grep{ ! /^:all$/i } @args;
  5         18  
120             # Generate all modifiers combinations as suffixes in alphabetical order.
121 2         6 my %already = map{$_ => 1} @args;
  3         13  
122 2 50       13 push @args, ":DEFAULT" unless $already{':DEFAULT'};
123 2         7 for my $v1 (qw/avis hvis vis ivis dvis/) { # avisl hvisl ?
124 10         17 for my $v2 ('1', '2', "") {
125 30         48 for my $v3 ('l', "") {
126 60 100 100     174 next if $v3 && $v1 !~ /^[ah]/; # 'l' only with avis or hvis
127 42         60 for my $v4 ('o', "") {
128 84         118 for my $v5 ('q', "") {
129 168         240 for my $v6 ('r', "") {
130 336         607 my $subname = $v1.$v2.$v3.$v4.$v5.$v6;
131 336 50       808 next if $already{$subname}++;
132 336         704 push @args, $subname;
133             }
134             }
135             }
136             }
137             }
138             }
139             }
140              
141 9 100       58 foreach my $subname (@args, ($exporting_default ? @EXPORT : ())) {
142 552 100       2376 next unless $subname =~ /^[a-zA-Z]/a; # skip :tag or $var
143 549         1498 push @EXPORT_OK, $subname;
144 9     9   82 no strict 'refs';
  9         22  
  9         3064  
145 549 100       2566 if (defined(*$subname{CODE})) {
146 58 50 50     178 warn "# $subname ALREADY DEFINED\n" if ($Debug//0) > 1;
147             } else {
148             # Only generate a 'forward' stub to allow prototype checks.
149             # Subs actually called will be defined via AUTOLOAD
150 491         2049 _generate_sub($subname, 1);
151             }
152             }
153              
154 9 50 66     60 @args = (':null') if @_ && !@args;
155              
156 9 50       38 warn "Passing to Exporter::import ",&_dbavis(@args),"\n"
157             if $Debug;
158              
159 9         195405 __PACKAGE__->export_to_level(1, $class, @args);
160             }
161              
162             sub AUTOLOAD { # invoked on call to undefined *method*
163 31     31   1222775 our $AUTOLOAD;
164 31         140 _SaveAndResetPunct();
165 31         77 our $Debug;
166 31         86 local $Debug = $AUTOLOAD_debug;
167 31 50       123 carp "AUTOLOAD $AUTOLOAD" if $Debug;
168 31         311 _generate_sub($AUTOLOAD);
169 31         144 _RestorePunct();
170 9     9   87 no strict 'refs';
  9         55  
  9         39999  
171 31         1160 goto &$AUTOLOAD;
172             }
173             #sub DESTROY {} #unnecessary: No D::D::Interp objects are ever instantiated
174              
175             ############################################################################
176             # Internal debug-message utilities
177              
178 0     0 0 0 sub oops(@) { @_=("\n".(caller)." oops:\n",@_,"\n"); goto &Carp::confess }
  0         0  
179 0     0 0 0 sub btwN($@) { my $N=shift; local $_=join("",@_); s/\n\z//s; printf "%4d: %s\n",(caller($N))[2],$_; }
  0         0  
  0         0  
  0         0  
180 0     0 0 0 sub btw(@) { unshift @_,0; goto &btwN }
  0         0  
181              
182             sub _chop_ateval($) { # remove "at (eval N) line..." from an exception message
183 0     0   0 (local $_ = shift) =~ s/ at \(eval[^\)]*\) line \d+[^\n]*\n?\z//s;
184 0         0 $_
185             }
186             sub _croak_or_confess(@) {
187             # Chain to croak, or to confess if there is an eval in the call stack
188 0 0   0   0 if (Carp::longmess("") =~ /\beval\b/) {
189 0         0 goto &Carp::confess;
190             }
191 0         0 goto &Carp::croak;
192             }
193              
194 0 0   0   0 sub _tf($) { $_[0] ? "T" : "F" }
195 0 0   0   0 sub _showfalse(_) { $_[0] ? $_[0] : 0 }
196             sub _dbvisnew($) {
197 800     800   1213 my $v = shift;
198 800         3760 Data::Dumper->new([$v])->Terse(1)->Indent(0)->Quotekeys(0)->Useqq(1)
199             #->Useperl(1)
200             ###->Sortkeys(\&__sortkeys)->Pair("=>")
201             }
202 800     800   7993 sub _dbvis(_) {chomp(my $s=_dbvisnew(shift)->Useqq(1)->Dump); $s }
  800         52870  
203 0     0   0 sub _dbvisq(_){chomp(my $s=_dbvisnew(shift)->Useqq(0)->Dump); $s }
  0         0  
204 0     0   0 sub _dbvis1(_){chomp(my $s=_dbvisnew(shift)->Maxdepth(1)->Useqq(1)->Dump); $s }
  0         0  
205 0     0   0 sub _dbvis2(_){chomp(my $s=_dbvisnew(shift)->Maxdepth(3)->Useqq(1)->Dump); $s }
  0         0  
206 0     0   0 sub _dbavis(@){ "(" . join(", ", map{_dbvis} @_) . ")" }
  0         0  
207 0     0   0 sub _dbavis2(@){ "(" . join(", ", map{_dbvis2} @_) . ")" }
  0         0  
208 0 0   0   0 sub _dbrvis(_) { (ref($_[0]) ? addrvis(refaddr $_[0]) : "")._dbvis($_[0]) }
209 0 0   0   0 sub _dbrvis2(_){ (ref($_[0]) ? addrvis(refaddr $_[0]) : "")._dbvis2($_[0]) }
210 0     0   0 sub _dbravis2(@){ "(" . join(", ", map{_dbrvis2} @_) . ")" }
  0         0  
211             sub _dbshow(_) {
212 0     0   0 my $v = shift;
213 0 0       0 blessed($v) ? "(".blessed($v).")".$v # stringify with (classname) prefix
214             : _dbvis($v) # something else
215             }
216             our $_dbmaxlen = 300;
217 0 0   0   0 sub _dbrawstr(_) { "«".(length($_[0])>$_dbmaxlen ? substr($_[0],0,$_dbmaxlen-3)."..." : $_[0])."»" }
218             sub _dbstr($) {
219 0     0   0 local $_ = shift;
220 0 0       0 return "undef" if !defined;
221 0         0 s/\x{0a}/\N{U+2424}/sg; # a special NL glyph
222 0         0 s/ /\N{U+00B7}/sg; # space -> Middle Dot
223 0         0 s/[\x{00}-\x{1F}]/ chr( ord($&)+0x2400 ) /aseg;
  0         0  
224 0         0 $_
225             }
226             sub _dbstrposn($$) {
227 0     0   0 local $_ = shift;
228 0         0 my $posn = shift;
229 0         0 local $_dbmaxlen = max($_dbmaxlen+8, $posn+8);
230 0         0 my $visible = _dbstr($_); # simplified 'controlpics'
231 0         0 "posn=$posn shown at '(<<HERE)':"
232             . substr($visible, 0, $posn+1)."(<<HERE)".substr($visible,$posn+1)
233             }
234             ############################################################################
235              
236              
237             #################### Configuration Globals #################
238              
239             our ($Debug, $MaxStringwidth, $Truncsuffix, $Objects,
240             $Refaddr, $Foldwidth, $Foldwidth1,
241             $Useqq, $Quotekeys, $Sortkeys,
242             $Maxdepth, $Maxrecurse, $Deparse, $Deepcopy);
243              
244             $Debug = 0 unless defined $Debug;
245             $MaxStringwidth = 0 unless defined $MaxStringwidth;
246             $Truncsuffix = "..." unless defined $Truncsuffix;
247             $Objects = 1 unless defined $Objects;
248             $Refaddr = 0 unless defined $Refaddr;
249             $Foldwidth = undef unless defined $Foldwidth; # undef auto-detects
250             $Foldwidth1 = undef unless defined $Foldwidth1; # override for 1st
251              
252             # The following override Data::Dumper defaults
253             # Initial D::D values are captured once when we are first loaded.
254             #
255             #$Useqq = "unicode:controlpic" unless defined $Useqq;
256             $Useqq = "unicode" unless defined $Useqq;
257             $Quotekeys = 0 unless defined $Quotekeys;
258             $Sortkeys = \&__sortkeys unless defined $Sortkeys;
259             $Maxdepth = $Data::Dumper::Maxdepth unless defined $Maxdepth;
260             $Maxrecurse = $Data::Dumper::Maxrecurse unless defined $Maxrecurse;
261             $Deparse = 0 unless defined $Deparse;
262             $Deepcopy = 0 unless defined $Deepcopy;
263              
264             #################### Methods #################
265              
266             has dd => (
267             is => 'ro',
268             lazy => 1,
269             default => sub{
270             my $self = shift;
271             Data::Dumper->new([],[])
272             ->Terse(1)
273             ->Indent(0)
274             ->Sparseseen(1)
275             ->Useqq($Useqq)
276             ->Quotekeys($Quotekeys)
277             ->Sortkeys($Sortkeys)
278             ->Maxdepth($Maxdepth)
279             ->Maxrecurse($Maxrecurse)
280             ->Deparse($Deparse)
281             ->Deepcopy($Deepcopy)
282             },
283             # This generates pass-through methods which call the dd object
284             handles => [qw/Values Useqq Quotekeys Trailingcomma Pad Varname Quotekeys
285             Maxdepth Maxrecurse Useperl Sortkeys Deparse Deepcopy
286             /],
287             );
288              
289             # Config values which have no counter part in Data::Dumper
290             has Debug => (is=>'rw', default => sub{ $Debug });
291             has MaxStringwidth => (is=>'rw', default => sub{ $MaxStringwidth });
292             has Truncsuffix => (is=>'rw', default => sub{ $Truncsuffix });
293             has Objects => (is=>'rw', default => sub{ $Objects });
294             has Refaddr => (is=>'rw', default => sub{ $Refaddr });
295             has Foldwidth => (is=>'rw', default => sub{
296             $Foldwidth // do{
297             _set_default_Foldwidth();
298             $Foldwidth
299             }
300             });
301             has Foldwidth1 => (is=>'rw', default => sub{ $Foldwidth1 });
302             has _Listform => (is=>'rw');
303              
304             # Make "setters" return the outer object $self
305             around [qw/Values Useqq Quotekeys Trailingcomma Pad Varname Quotekeys
306             Maxdepth Maxrecurse Useperl Sortkeys Deparse Deepcopy
307              
308             Debug MaxStringwidth Truncsuffix Objects Refaddr
309             Foldwidth Foldwidth1 _Listform
310             /] => sub{
311             my $orig = shift;
312             my $self = shift;
313             #Carp::cluck("##around (@_)\n");
314             if (@_ > 0) {
315             $self->$orig(@_);
316             return $self;
317             }
318             $self->$orig
319             };
320              
321             ############### Utility Functions #################
322              
323             #---------------------------------------------------------------------------
324             # Display an address as <decimal:hex> showing only the last few digits.
325             # The number of digits shown increases when collisions occur.
326             # The arg can be a numeric address or a ref from which the addr is taken.
327             # If a ref the result is REFTYPEorOBJTYPE<dec:hex> otherwise just <dec:hex>
328             our $addrvis_ndigits = 3;
329             our $addrvis_seen = {}; # full (decimal) address => undef
330             our $addrvis_dec_abbrs = {}; # abbreviated decimal digits => undef
331             sub _abbr_hex($) {
332 170573     170573   548363 substr(sprintf("%0*x", $addrvis_ndigits, $_[0]), -$addrvis_ndigits) }
333             sub _abbr_dec($) {
334 176946     176946   569954 substr(sprintf("%0*d", $addrvis_ndigits, $_[0]), -$addrvis_ndigits) }
335             sub addrvis(_) {
336 170575   100 170575 1 3102436 my $arg = shift // return("undef");
337 170573         254301 my $refstr = ref($arg);
338 170573         214684 my $addr;
339 170573 100       403921 if ($refstr ne "") { $addr = refaddr($arg) }
  39 50       79  
340 170534         233265 elsif (looks_like_number($arg)) { $addr = $arg }
341             else {
342 0         0 carp("addrvis arg '$arg' is neither a ref or a number\n");
343 0         0 return ""
344             }
345              
346 170573 100       359558 if (! exists $addrvis_seen->{$addr}) {
347 2168         3329 my $dec_abbr = _abbr_dec($addr);
348 2168         5167 while (exists $addrvis_dec_abbrs->{$dec_abbr}) {
349 3         7 ++$addrvis_ndigits;
350 3         454 %$addrvis_dec_abbrs = map{ (_abbr_dec($_) => undef) } keys %$addrvis_seen;
  3202         4929  
351 3         277 $dec_abbr = _abbr_dec($addr);
352             }
353 2168         5093 $addrvis_dec_abbrs->{$dec_abbr} = undef;
354 2168         4369 $addrvis_seen->{$addr} = undef;
355             }
356             #$refstr ne "" ? $refstr.'<'._abbr_dec($addr).':'._abbr_hex($addr).'>'
357             # : _abbr_dec($addr).':'._abbr_hex($addr)
358 170573         299004 $refstr.'<'._abbr_dec($addr).':'._abbr_hex($addr).'>'
359             }
360             sub addrvisl(_) {
361             # Return bare "hex:dec" or "Typename hex:dec"
362 2 100   2 1 7 &addrvis =~ s/^([^\<]*)\<(.*)\>$/ $1 ? "$1 $2" : $2 /er or oops
  2 50       26  
363             }
364             sub addrvis_digits(;$) {
365 1 50   1 0 416 return $addrvis_ndigits if ! defined $_[0]; # "get" request
366 1 50       4 if ($_[0] <= $addrvis_ndigits) {
367 0         0 return $addrvis_ndigits; # can not decrease
368             }
369 1         4 $addrvis_ndigits = $_[0];
370 1         109 %$addrvis_dec_abbrs = map{ (_abbr_dec($_) => undef) } keys %$addrvis_seen;
  1000         1526  
371 1         93 $addrvis_ndigits;
372             }
373             sub addrvis_forget() {
374 2     2 0 723 $addrvis_seen = {};
375 2         237 $addrvis_dec_abbrs = {};
376 2         8 $addrvis_ndigits = 3;
377             }
378              
379             =for Pod::Coverage addrvis_digits addrvis_forget
380              
381             =cut
382              
383 50   100 50 1 34292 sub u(_) { $_[0] // "undef" }
384             sub quotekey(_); # forward. Implemented after regex declarations.
385              
386             sub __stringify($) {
387 29 50   29   99 if (defined(my $class = blessed($_[0]))) {
388 0 0       0 return "$_[0]" if overload::Method($class,'""');
389             }
390 29         59 $_[0]
391             }
392              
393 9 50       22410 use constant _SHELL_UNSAFE_REGEX =>
394 9     9   87 ($^O eq "MSWin32" ? qr/[^-=\w_:\.,\\]/ : qr/[^-=\w_\/:\.,]/);
  9         20  
395              
396             sub __forceqsh(_) {
397 12     12   23 local $_ = shift;
398 12 100       38 return "undef" if !defined; # undef without quotes
399 11 50       23 $_ = vis($_) if ref;
400 11 50       33 if ($^O eq "MSWin32") {
401             # Backslash usually need not be protected, except:
402             # \" quotes the " whether inside "quoes" or bare (!)
403             # \\ quotes the \ ONLY(?) if immediately followed by \"
404 0         0 s/\\(?=")/\\\\/g;
405 0         0 s/"/\\"/g;
406 0         0 return "\"${_}\""; # 6/7/23: UNtested
407             } else {
408             # Prefer "double quoted" if no shell escapes would be needed.
409 11 100       29 if (/["\$`!\\\x{00}-\x{1F}\x{7F}]/) {
410             # Unlike Perl, /bin/sh does not recognize any backslash escapes in '...'
411 1         4 s/'/'\\''/g; # foo'bar => foo'\''bar
412 1         11 return "'${_}'";
413             } else {
414 10         121 return "\"${_}\"";
415             }
416             }
417             }
418             sub qsh(_) {
419 20     20 1 13646 local $_ = __stringify(shift());
420 20 100 100     243 defined && !ref && ($_ !~ _SHELL_UNSAFE_REGEX)
421             && $_ ne "" && $_ ne "undef" ? $_ : __forceqsh
422             }
423             sub qshpath(_) { # like qsh but does not quote initial ~ or ~username
424 9     9 1 1033 local $_ = __stringify(shift());
425 9 50 33     51 return qsh($_) if !defined or ref;
426 9 50       63 my ($tilde_prefix, $rest) = /^( (?:\~[^\/\\]*[\/\\]?+)? )(.*)/xs or die;
427 9 100       46 $rest eq "" ? $tilde_prefix : $tilde_prefix.qsh($rest)
428             }
429              
430             # Should this have been called 'aqsh' ?
431 1     1 1 116 sub qshlist(@) { join " ", map{qsh} @_ }
  3         6  
432              
433             ########### Subs callable as either a Function or Method #############
434              
435             sub __getself { # Return $self if passed or else create a new object
436 7297     7297   15453 local $@;
437 7297         14474 my $blessed = eval{ blessed($_[0]) }; # In case a tie handler throws
  7297         28225  
438 7297 50       20104 croak _chop_ateval($@) if $@;
439 7297 100 100     83711 $blessed && $_[0]->isa(__PACKAGE__) ? shift : __PACKAGE__->new()
440             }
441 5564     5564   11337 sub __getself_s { &__getself->Values([$_[0]]) }
442 320     320   840 sub __getself_a { &__getself->Values([[@_]]) }
443             sub __getself_h {
444 140     140   369 my $obj = &__getself;
445 140 50       4141 ($#_ % 2)==1 or croak "Uneven arg count for key => val pairs";
446 140         1155 $obj->Values([{@_}])
447             }
448              
449             sub _EnabSpacedots {
450             # Append :spacedots to Useqq if Useqq matches the global default
451             # (and if the default used extended options).
452 1201     1201   399660 my $self = shift;
453 1201         5196 my $curr = $self->Useqq;
454 1201 50 50     48842 return $self if length($curr//"") <= 1 or $curr eq $Useqq;
      33        
455 0         0 $self->Useqq($curr.":spacedots")
456             }
457              
458             sub _generate_sub($;$) {
459             my ($arg, $proto_only) = @_;
460             (my $methname = $arg) =~ s/.*:://;
461             my sub error($) {
462             _croak_or_confess "Invalid sub/method name '$methname' (@_)\n"
463             }
464              
465             # Method names are ivis, dvis, vis, avis, or hvis with prepended
466             # or appended modifier letters or digits (in any order), with
467             # optional underscore separators.
468             local $_ = $methname;
469              
470             s/alvis/avisl/; # backwards compat.
471             s/hlvis/hvisl/; # backwards compat.
472              
473             s/^[^diha]*\K(?:lvis|visl)/avisl/; # 'visl' same as 'avisl' for bw compat.
474              
475             s/([ahid]?vis)// or error "can not infer the basic function";
476             my $basename = $1; # avis, hvis, ivis, dvis, or vis
477             my $N = s/(\d+)// ? $1 : undef;
478             my %mod = map{$_ => 1} split //, $_;
479             delete $mod{"_"}; # ignore underscores
480              
481             if (($Debug//0) > 1) {
482             warn "## (D=$Debug) methname=$methname base=$basename \$_=$_\n";
483             }
484             if ($basename =~ /^[id]/) {
485             error "'$1' is inapplicable to $basename" if /([ahl])/;
486             }
487             error "'$1' mis-placed: Only allowed as '${1}vis'" if /([ahi])/;
488              
489              
490             # All these subs can be called as either or methods or functions.
491             # If the first argument is an object it is used, otherwise a new object
492             # is created; then option-setting methods are called as implied by
493             # the specific sub name.
494             #
495             # Finally the _Do() method is invoked for primatives like 'vis'.
496             #
497             # For ivis/dvis, control jumps to _Interpolate() which uses the object
498             # repeatedly when calling primatives to interpolate values into the string.
499              
500             my $listform = '';
501             my $signature = $basename =~ /^[ah]/ ? '@' : '_'; # avis(@) ivis(_) vis(_)
502             my $code = "sub $methname($signature)";
503             if ($proto_only) {
504             $code .= ";";
505             } else {
506             if ($basename eq "vis") {
507             $code .= " { &__getself_s->_Listform('')";
508             }
509             elsif ($basename eq "avis") {
510             my $listform = delete($mod{l}) ? 'l' : 'a';
511             $code .= " { &__getself_a->_Listform('$listform')";
512             }
513             elsif ($basename eq "hvis") {
514             my $listform = delete($mod{l}) ? 'l' : 'h';
515             $code .= " { &__getself_h->_Listform('$listform')";
516             }
517             elsif ($basename eq "ivis") {
518             $code .= " { \@_ = ( &__getself" ;
519             }
520             elsif ($basename eq "dvis") {
521             $code .= " { \@_ = ( &__getself->_EnabSpacedots" ;
522             }
523             else { oops }
524              
525             $code .= "->Maxdepth($N)" if defined($N);
526             $code .= '->Objects(0)' if delete $mod{o};
527             $code .= '->Useqq(0)' if delete $mod{q};
528             $code .= '->Useqq("unicode:controlpics")' if delete $mod{c};
529             $code .= '->Refaddr(1)' if delete $mod{r};
530             $code .= '->Debug(2)' if delete $mod{d};
531              
532             if ($basename =~ /^([id])vis/) {
533             $code .= ", shift, '$1' ); goto &_Interpolate }";
534             } else {
535             $code .= "->_Do }";
536             }
537              
538             for (keys %mod) { error "Unknown or inappropriate modifier '$_'" }
539             }
540              
541             # To see the generated code
542             # use Data::Dumper::Interp qw/:debug :DEFAULT/; # or :all
543             if ($Debug) {
544             warn "# generated: $code\n";
545             }
546 54     54 1 27655 eval "$code"; oops "code=$code\n\$@=$@" if $@;
  54     6918 1 24217  
  6918     99 0 630863  
  1219     129 1 37019  
  67     46 0 33406  
  67     17 0 15207  
  103     17 0 14319  
  20         11390  
  17         10386  
  17         11403  
547             }#_generate_sub
548              
549              
550 41     41 1 34116 sub visnew() { __PACKAGE__->new() } # shorthand
551              
552              
553             ############# only internals follow ############
554              
555             BEGIN {
556 9 50   9   4923 if (! Data::Dumper->can("Maxrecurse")) {
557             # Supply if missing in older Data::Dumper
558 0         0 eval q(sub Data::Dumper::Maxrecurse {
559             my($s, $v) = @_;
560             @_ == 2 ? (($s->{Maxrecurse} = $v), return $s)
561             : $s->{Maxrecurse}//0;
562             });
563 0 0       0 die $@ if $@;
564             }
565             }
566              
567             sub _get_terminal_width() { # returns undef if unknowable
568 27 100   10   192 if (u($ENV{COLUMNS}) =~ /^[1-9]\d*$/) {
569 2         24 return $ENV{COLUMNS}; # overrides actual terminal width
570             } else {
571 8         54 local *_; # Try to avoid clobbering special filehandle "_"
572             # This does not actualy work; https://github.com/Perl/perl5/issues/19142
573              
574             my $fh = -t STDERR ? *STDERR :
575             -t STDOUT ? *STDOUT :
576             -t STDIN ? *STDIN :
577 8 50       122 do{my $fh; for("/dev/tty",'CONOUT$') { last if open $fh, $_ } $fh} ;
  8 50       24  
  8 50       42  
  16 50       516  
  8         51  
578 8         21 my $wmsg = ""; # Suppress a "didn't work" warning from Term::ReadKey.
579             # On some platforms (different libc?) "stty" directly
580             # outputs "stdin is not a tty" which we can not trap.
581             # Probably this is a Term::Readkey bug where it should
582             # redirect such messages to /dev/null...
583 8         18 my ($width, $height) = do {
584 8     8   133 local $SIG{'__WARN__'} = sub { $wmsg .= $_[0] };
  8         110087  
585 8 50       115 $fh ? Term::ReadKey::GetTerminalSize($fh) : ()
586             };
587 8         722 return $width; # possibly undef (sometimes seems to be zero ?!?)
588             }
589             }
590              
591             sub _set_default_Foldwidth() {
592 10     10   62 _SaveAndResetPunct();
593 10   100     49 $Foldwidth = _get_terminal_width || 80;
594 10         193 _RestorePunct();
595 10         150 undef $Foldwidth1;
596             }
597              
598 9     9   78 use constant _UNIQUE => substr(refaddr \&oops,-5);
  9         22  
  9         1785  
599             use constant {
600 9         18 _MAGIC_NOQUOTES_PFX => "|NQMagic${\_UNIQUE}|",
  9         28  
601 9         21 _MAGIC_KEEPQUOTES_PFX => "|KQMagic${\_UNIQUE}|",
602 9         25 _MAGIC_REFADDR => "|RAMagic${\_UNIQUE}|",
603 9         9200 _MAGIC_ELIDE_NEXT => "|ENMagic${\_UNIQUE}|",
604 9     9   75 };
  9         21  
605              
606             #---------------------------------------------------------------------------
607             my $my_maxdepth;
608             our $my_visit_depth = 0;
609              
610             my ($maxstringwidth, $truncsuffix, $objects, $opt_refaddr, $listform, $debug);
611             my ($sortkeys);
612              
613             sub _Do {
614 6024 50   6024   15254 oops unless @_ == 1;
615 6024         11670 my $self = $_[0];
616              
617 6024         9537 local $_;
618 6024         14617 &_SaveAndResetPunct;
619              
620             ($maxstringwidth, $truncsuffix, $objects, $opt_refaddr, $listform, $debug)
621 6024         25361 = @$self{qw/MaxStringwidth Truncsuffix Objects Refaddr _Listform Debug/};
622 6024         22479 $sortkeys = $self->Sortkeys;
623              
624 6024 50 100     93222 $maxstringwidth = 0 if ($maxstringwidth //= 0) >= INT_MAX;
625 6024   50     13398 $truncsuffix //= "...";
626 6024 100 100     21563 $objects = [ $objects ] unless ref($objects //= []) eq 'ARRAY';
627              
628 6024         159002 my @orig_values = $self->dd->Values;
629 6024 50       59831 croak "Exactly one item may be in Values" if @orig_values != 1;
630 6024         12032 my $original = $orig_values[0];
631 6024 50       13421 btw "##ORIGINAL=",u($original),"=",_dbvis($original) if $debug;
632              
633 6024 50       14512 _croak_or_confess "*vis($original) called in void context.\nDid you forget to 'say ...'?"
634             if ! defined wantarray;
635              
636             # Allow one extra level if we wrapped the user's args in __getself_[ah]
637 6024   100     18747 $my_maxdepth = $self->Maxdepth || INT_MAX;
638 6024 50 66     97934 ++$my_maxdepth if $listform && $my_maxdepth < INT_MAX;
639              
640 6024 50       13214 oops unless $my_visit_depth == 0;
641 6024         19441 my $modified = $self->visit($original); # see Data::Visitor
642              
643 6024 50       40096 btw "## DD input : ",_dbvis($modified) if $debug;
644 6024         177251 $self->dd->Values([$modified]);
645              
646             # Always call Data::Dumper with Indent(0) and Pad("") to get a single
647             # maximally-compact string, and then manually fold the result to Foldwidth,
648             # inserting the user's Pad before each line *except* the first.
649             #
650             # Also disable Maxdepth because we handle that ourself (see visit_ref).
651 6024         72169 my $users_Maxdepth = $self->Maxdepth; # implemented by D::D
652 6024         84185 $self->Maxdepth(0);
653 6024         16486 my $users_pad = $self->Pad();
654 6024         89519 $self->Pad("");
655              
656 6024         10954 my ($dd_result, $our_result);
657 6024         15606 my ($sAt, $sQ) = ($@, $?);
658 6024         9884 { my $dd_warning = "";
  6024         10342  
659              
660 6024     0   8695 { local $SIG{__WARN__} = sub{ $dd_warning .= $_[0] };
  6024         39682  
  0         0  
661 6024         13446 eval{ $dd_result = $self->dd->Dump };
  6024         161325  
662             }
663 6024 50 33     147578 if ($dd_warning || $@) {
664 0 0       0 warn "Data::Dumper complained:\n$dd_warning\n$@" if $debug;
665 0         0 ($@, $?) = ($sAt, $sQ);
666 0         0 $our_result = $self->dd->Values([$original])->Dump;
667             }
668             }
669 6024         18301 ($@, $?) = ($sAt, $sQ);
670 6024         21244 $self->Pad($users_pad);
671 6024         19217 $self->Maxdepth($users_Maxdepth);
672              
673 6024   66     103459 $our_result //= $self->_postprocess_DD_result($dd_result, $original);
674              
675             # Allow deletion of the possibly-recursive clone
676 6024         27272 circular_off($modified);
677 6024         247019 $self->dd->Values([]);
678              
679 6024         71193 &_RestorePunct;
680 6024         37580 $our_result;
681             }
682              
683             #---------------------------------------------------------------------
684             # methods called from Data::Visitor when transforming the input
685              
686             sub _object_subst($) {
687 319     319   571 my $item = shift;
688 319         496 my $overload_depth;
689             CHECKObject: {
690 319 100       603 if (my $class = blessed($item)) {
  479         1660  
691 319         520 my $enabled;
692             OSPEC:
693 319         673 foreach my $ospec (@$objects) {
694 362 100       1224 if (ref($ospec) eq "Regexp") {
695 46         102 my @stack = ($class);
696 46         69 my %seen;
697 46         103 while (my $c = shift @stack) {
698 78 100       472 $enabled=1, last OSPEC if $c =~ $ospec;
699 48 50       128 last CHECKObject if $seen{$c}++; # circular ISAs !
700 9     9   74 no strict 'refs';
  9         20  
  9         23770  
701 48         66 push @stack, @{"${c}::ISA"};
  48         238  
702             }
703             } else {
704 316 100 100     1401 $enabled=1, last OSPEC if ($ospec eq "1" || $item->isa($ospec));
705             }
706             }
707             last CHECKObject
708 319 100       2187 unless $enabled;
709 299 100       1133 if (overload::Overloaded($item)) {
710 160 50       9539 btw '@@@repl overloaded ',"\'$class\'" if $debug;
711             # N.B. Overloaded(...) also returns true if it's a NAME of an
712             # overloaded package; should not happen in this case.
713 160 50       421 warn("Recursive overloads on $item ?\n"),last
714             if $overload_depth++ > 10;
715             # Stringify objects which have the stringification operator
716 160 100       379 if (overload::Method($class,'""')) {
717 155 50       5474 my $prefix = _show_as_number($item) ? _MAGIC_NOQUOTES_PFX : "";
718 155 50       390 btw '@@@repl prefix="',$prefix,'"' if $debug;
719 155         488 $item = $item.""; # stringify;
720 155 50       9026 if ($item !~ /^${class}=REF/) {
721 155         426 $item = "${prefix}($class)$item";
722             } else {
723             # The "stringification" looks like Perl's default; don't prefix it
724             }
725 155 50       368 btw '@@@repl stringified:',$item if $debug;
726 155         486 redo CHECKObject;
727             }
728             # Substitute the virtual value behind an overloaded deref operator
729 5 100       147 if (overload::Method($class,'@{}')) {
730 1 50       37 btw '@@@repl (overload...)' if $debug;
731 1         2 $item = \@{ $item };
  1         28  
732 1         8 redo CHECKObject;
733             }
734 4 100       99 if (overload::Method($class,'%{}')) {
735 1 50       33 btw '@@@repl (overload...)' if $debug;
736 1         2 $item = \%{ $item };
  1         26  
737 1         26 redo CHECKObject;
738             }
739 3 100       72 if (overload::Method($class,'${}')) {
740 1 50       34 btw '@@@repl (overload...)' if $debug;
741 1         3 $item = \${ $item };
  1         28  
742 1         8 redo CHECKObject;
743             }
744 2 100       47 if (overload::Method($class,'&{}')) {
745 1 50       33 btw '@@@repl (overload...)' if $debug;
746 1         2 $item = \&{ $item };
  1         26  
747 1         9 redo CHECKObject;
748             }
749 1 50       24 if (overload::Method($class,'*{}')) {
750 1 50       34 btw '@@@repl (overload...)' if $debug;
751 1         3 $item = \*{ $item };
  1         29  
752 1         6 redo CHECKObject;
753             }
754             }
755 139 100       8397 if ($class eq 'Regexp') {
756             # D::D will just stringify it, which is fine except actual tabs etc.
757             # will be shown as themselves and not \t etc.
758             # We try to fix that in _postprocess_DD_result;
759             } else {
760             # No overloaded operator (that we care about);
761             # substitute addrvis(obj)
762 1 50       5 btw '@@@repl (no overload repl, not Regexp)' if $debug;
763 1         4 $item = _MAGIC_NOQUOTES_PFX.addrvis($item);
764             }
765             }
766             }#CHECKObject
767             $item
768 319         1524 }#_object_subst
769              
770             sub visit_value {
771 8195     8195 1 207258 my $self = shift;
772 8195 50       18173 say "!V value ",_dbravis2(@_)," depth:$my_visit_depth" if $debug;
773 8195         13145 my $item = shift;
774             # N.B. Not called for hash keys (short-circuited in visit_hash_key)
775              
776 8195 100       17912 return $item
777             if !defined($item);
778              
779 8178 100       21576 return _object_subst($item)
780             if defined(blessed $item);
781              
782 7859 100       20106 return $item
783             if reftype($item); # some other (i.e. not blessed) reference
784              
785             # Prepend a "magic prefix" (later removed) to items which Data::Dumper is
786             # likely to represent wrongly or anyway not how we want:
787             #
788             # 1. Scalars set to strings like "6" will come out as a number 6 rather
789             # than "6" with Useqq(1) or Useperl(1) (string-ness is preserved
790             # with other options). IMO this is a Data::Dumper bug which the
791             # maintainers won't fix it because the difference isn't functionally
792             # relevant to correctly-written Perl code. However we want to help
793             # humans debug their software by showing the representation they
794             # most likely used to create the datum.
795             #
796             # 2. Floating point values come out as "strings" to avoid some
797             # cross-platform issue. For our purposes we want all numbers
798             # to appear unquoted.
799             #
800 7857 100 66     40309 if (looks_like_number($item) && $item !~ /^0\d/) {
    100 66        
      100        
801 2998 100       8005 my $prefix = _show_as_number($item) ? _MAGIC_NOQUOTES_PFX
802             : _MAGIC_KEEPQUOTES_PFX ;
803 2998         7080 $item = $prefix.$item;
804 2998 50       7025 btw '@@@repl prefixed item:',$item if $debug;
805             }
806              
807             # Truncacte overly-long strings
808             elsif ($maxstringwidth && !_show_as_number($item)
809             && length($item) > $maxstringwidth + length($truncsuffix)) {
810 9 50       21 btw '@@@repl truncating ',substr($item,0,10),"..." if $debug;
811 9         24 $item = "".substr($item,0,$maxstringwidth).$truncsuffix;
812             }
813             $item
814 7857         27371 }#visit_value
815              
816             sub visit_hash_key {
817 1518     1518 1 12538 my ($self, $item) = @_;
818 1518 50       3292 say "!V visit_hash_key ",_dbravis2($item)," depth:$my_visit_depth" if $debug;
819 1518         4496 return $item; # don't truncate or otherwise munge
820             }
821              
822             sub _prefix_refaddr($;$) {
823 1998     1998   3612 my ($item, $original) = @_;
824             # If enabled by Refaddr(true):
825             #
826             # Prefix (the formatted representation of) a ref with it's abbreviated
827             # address. This is done by wrapping the ref in a temporary [array] with the
828             # prefix, and unwrapping the Data::Dumper result in _postprocess_DD_result().
829             #
830             # However don't do this if $item already has an addrvis() substituted,
831             # which happens if an object does not stringify or provide another overload
832             # replacement -- see _object_subst().
833 1998 100 66     5677 return $item
      100        
834             unless $opt_refaddr && (!$listform || $my_visit_depth > 0);
835 37   33     133 my $pfx = addrvis(refaddr($original//$item));
836 37         98 my $ix = index($item,$pfx);
837 37 50       329 say "_prefix_refaddr: pfx=$pfx ix=$ix original=",_dbvis1($original)," item=$item" if $debug;
838 37 50       134 return $item if $ix >= 0;
839 37         120 $item = [ _MAGIC_REFADDR.$pfx, $item, _MAGIC_ELIDE_NEXT, ];
840 37 50       81 btwN 1, '@@@addrvis-prefixed object:',_dbvis2($item) if $debug;
841 37         74 $item
842             }#_prefix_refaddr
843              
844             sub visit_object {
845 319     319 1 10942 my $self = shift;
846 319         597 my $item = shift;
847 319 50       800 say "!V object a=",addrvis(refaddr $item)," depth:$my_visit_depth"," item=",_dbvis1($item) if $debug;
848 319         705 my $original = $item;
849              
850 319         635 local $my_visit_depth = $my_visit_depth + 1;
851             # FIXME: with Objects(0) we should visit object internals so $my_maxdepth
852             # can be applied correctly. Currently we just leave object refs as-is
853             # for D::D to expand, and Maxdepth will be handled incorrectly if the
854             # is underneath a magic_refaddr wrapper or avis/hvis top wrapper.
855              
856             # First register the ref (to detect duplicates);
857             # this calls visit_seen() which usually substitutes something
858 319         1005 my $nitem = $self->SUPER::visit_object($item);
859 319 50       3751 say "! (obj) new: ",_dbvis1($item), " --> ",_dbrvis2($nitem) if $debug;
860 319         656 $item = $nitem;
861              
862 319         663 $item = _prefix_refaddr($item, $original);
863 319         1276 $item
864             }#visit_object
865              
866             sub visit_ref {
867 1679     1679 1 57004 my ($self, $item) = @_;
868 1679 100       4289 if (ref($item) eq 'ARRAY') {
869 546 50       1647 say "!V ref A=",addrvis(refaddr $item)," depth:$my_visit_depth max:$my_maxdepth item=",_dbavis2(@$item) if $debug;
870             } else {
871 1133 50       2751 say "!V ref a=",addrvis(refaddr $item)," depth:$my_visit_depth max:$my_maxdepth item=",_dbvis1($item) if $debug;
872             }
873 1679         2693 my $original = $item;
874              
875             # The Refaddr option introduces [...] wrappers in the tree and so
876             # Data::Dumper's Maxdepth() option will not work as we intend.
877             # Therefore we implement Maxdepth ourself
878 1679 50       3682 if ($my_visit_depth >= $my_maxdepth) {
879 0 0       0 oops unless $my_visit_depth == $my_maxdepth;
880 0         0 $item = _MAGIC_NOQUOTES_PFX.addrvis($item);
881 0 0       0 say "! maxdepth reached, returning ",_dbvis2($item) if $debug;
882 0         0 return $item
883             }
884              
885             # First descend into the structure, probably returning a clone
886 1679         2935 local $my_visit_depth = $my_visit_depth + 1;
887 1679         4993 my $nitem = $self->SUPER::visit_ref($item);
888 1679 50       33085 say "! (ref) new: ",_dbvis2($item), " --> ",_dbvis2($nitem) if $debug;
889 1679         2687 $item = $nitem;
890              
891             # Prepend the original address to whatever the representation is now
892 1679         3413 $item = _prefix_refaddr($item, $original);
893              
894 1679         5158 $item
895             }
896             sub visit_hash_entries {
897 561     561 1 22187 my ($self, $hash) = @_;
898             # Visit in sorted order
899 1518         9686 return map { $self->visit_hash_entry( $_, $hash->{$_}, $hash ) }
900 561 100       1429 (ref($sortkeys) ? @{ $sortkeys->($hash) } : (sort keys %$hash));
  553         1325  
901             }
902              
903             sub visit_glob {
904 3     3 1 71 my ($self, $item) = @_;
905 3 50       9 say "!V glob ref()=",ref($item)," depth:$my_visit_depth"," item=",_dbravis2($item) if $debug;
906             # By default Data::Visitor will create a new anon glob in the output tree.
907             # Instead, put the original into the output so the user can recognize
908             # it e.g. "*main::STDOUT" instead of an anonymous from Symbol::gensym
909 3         9 return $item
910             }
911              
912             sub visit_seen {
913 18     18 1 550 my ($self, $data, $first_result) = @_;
914 18 50       46 say "!V seen orig=",_dbrvis2($data)," depth:$my_visit_depth"," 1stres=",_dbrvis2($first_result)
915             if $debug;
916              
917             # $data is a ref which has been visited before, i.e. there is a circularity.
918             # Data::Dumper will display a $VAR->... expression.
919             # With the Refaddr option the $VAR index may be incorrect due to the
920             # temporary [...] wrappers inserted into the cloned tree.
921             #
922             # Therefore if Refaddr is in effect substitute an addrvis() string
923             # which the user will be able to match with other refs to the same thing.
924 18 100       43 if ($opt_refaddr) {
925 7         14 my $t = ref($data);
926 7 100       27 return _MAGIC_NOQUOTES_PFX.addrvis(refaddr $data)."[...]" if $t eq "ARRAY";
927 5 100       22 return _MAGIC_NOQUOTES_PFX.addrvis(refaddr $data)."{...}" if $t eq "HASH";
928 3 100       17 return _MAGIC_NOQUOTES_PFX.addrvis(refaddr $data)."\\..." if $t eq "SCALAR";
929 1         4 return _MAGIC_NOQUOTES_PFX.addrvis($data);
930             }
931              
932             $first_result
933 11         27 }
934              
935             #---------------------------------------------------------------------
936             sub _preprocess { # Modify the cloned data
937 9     9   81 no warnings 'recursion';
  9         22  
  9         9052  
938 0     0   0 my ($self, $cloned_itemref, $orig_itemref) = @_;
939 0         0 my ($debug, $seenhash) = @$self{qw/Debug Seenhash/};
940              
941 0 0       0 btw '##pp AAA cloned=",addrvis($cloned_itemref)," -> ',_dbvis($$cloned_itemref) if $debug;
942 0 0       0 btw '## orig=",addrvis($orig_itemref)," -> ",_dbvis($$orig_itemref)' if $debug;
943              
944             # Pop back if this item was visited previously
945 0 0       0 if ($seenhash->{ refaddr($cloned_itemref) }++) {
946 0 0       0 btw ' Seen already' if $debug;
947             return
948 0         0 }
949              
950             # About TIED VARIABLES:
951             # We must never modify a tied variable because of user-defined side-effects.
952             # So when we want to replace a tied variable we untie it first, if possible.
953             # N.B. The whole structure was cloned, so this does not untie the
954             # user's variables.
955             #
956             # All modifications (untie and over-writing) is done in eval{...} in case
957             # the data is read-only or an UNTIE handler throws -- in which case we leave
958             # the cloned item as it is. This occurs e.g. with the 'Readonly' module;
959             # I tried using Readonly::Clone (insterad of Clone::clone) to copy the input,
960             # since it is supposed to make a mutable copy; but it has bugs with refs to
961             # other refs, and doesn't actually make everything mutable; it was a big mess
962             # so now taking the simple way out.
963              
964             # Side note: Taking a ref to a member of a tied container,
965             # e.g. \$tiedhash{key}, actually returns an overloaded object or some other
966             # magical thing which, every time it is de-referenced, FETCHes the datum
967             # into a temporary.
968             #
969             # There is a bug somewhere which makes it unsafe to store these fake
970             # references inside tied variables because after the variable is 'untie'd
971             # bad things can happen (refcount problems?). So after a lot of mucking
972             # around I gave up trying to do anything intelligent about tied data.
973             # I still have to untie variables before over-writing them with substitute
974             # content.
975              
976             # Note: Our Item is only ever a scalar, either the top-level item from the
977             # user or a member of a container we unroll below. In either case the
978             # scalar could be either a ref to something or a non-ref value.
979              
980 0         0 eval {
981 0 0       0 if (tied($$cloned_itemref)) {
982 0 0       0 btw ' Item itself is tied' if $debug;
983 0         0 my $copy = $$cloned_itemref;
984 0         0 untie $$cloned_itemref;
985 0         0 $$cloned_itemref = $copy; # n.b. $copy might be a ref to a tied variable
986 0 0       0 oops if tied($$cloned_itemref);
987             }
988              
989 0   0     0 my $rt = reftype($$cloned_itemref) // ""; # "" if item is not a ref
990 0 0       0 if (reftype($cloned_itemref) eq "SCALAR") {
991 0 0       0 oops if $rt;
992 0 0       0 btw '##pp item is non-ref scalar; stop.' if $debug;
993             return
994 0         0 }
995              
996             # Item is some kind of ref
997 0 0       0 oops unless reftype($cloned_itemref) eq "REF";
998 0 0       0 oops unless reftype($orig_itemref) eq "REF";
999              
1000 0 0 0     0 if ($rt eq "SCALAR" || $rt eq "LVALUE" || $rt eq "REF") {
    0 0        
    0          
1001 0 0       0 btw '##pp dereferencing ref-to-scalarish $rt' if $debug;
1002 0         0 $self->_preprocess($$cloned_itemref, $$orig_itemref);
1003             }
1004             elsif ($rt eq "ARRAY") {
1005 0 0       0 btw '##pp ARRAY ref' if $debug;
1006 0 0       0 if (tied @$$cloned_itemref) {
1007 0 0       0 btw ' aref to *tied* ARRAY' if $debug;
1008 0         0 my $copy = [ @$$cloned_itemref ]; # only 1 level
1009 0         0 untie @$$cloned_itemref;
1010 0         0 @$$cloned_itemref = @$copy;
1011             }
1012 0         0 for my $ix (0..$#{$$cloned_itemref}) {
  0         0  
1013 0         0 $self->_preprocess(\$$cloned_itemref->[$ix], \$$orig_itemref->[$ix]);
1014             }
1015             }
1016             elsif ($rt eq "HASH") {
1017 0 0       0 btw '##pp HASH ref' if $debug;
1018 0 0       0 if (tied %$$cloned_itemref) {
1019 0 0       0 btw ' href to *tied* HASH' if $debug;
1020 0         0 my $copy = { %$$cloned_itemref }; # only 1 level
1021 0         0 untie %$$cloned_itemref;
1022 0         0 %$$cloned_itemref = %$copy;
1023 0 0       0 die if tied %$$cloned_itemref;
1024             }
1025             #For easier debugging, do in sorted order
1026 0 0       0 btw ' #### iterating hash values...' if $debug;
1027 0         0 for my $key (sort keys %$$cloned_itemref) {
1028 0         0 $self->_preprocess(\$$cloned_itemref->{$key}, \$$orig_itemref->{$key});
1029             }
1030             }
1031             };#eval
1032 0 0       0 if ($@) {
1033 0 0       0 btw "*EXCEPTION*, just returning\n$@\n" if $debug;
1034             }
1035             }
1036              
1037             sub _show_as_number(_) {
1038 4009     4009   301252 my $value = shift;
1039              
1040             # IMPORTANT: We must not do any numeric ops or comparisions
1041             # on $value because that may set some magic which defeats our attempt
1042             # to try bitstring unary & below (after a numeric compare, $value is
1043             # apparently assumed to be numeric or dual-valued even if it
1044             # is/was just a "string").
1045              
1046 4009 100       9330 return 0 if !defined $value;
1047              
1048             # if the utf8 flag is on, it almost certainly started as a string
1049 4008 100 100     17088 return 0 if (ref($value) eq "") && utf8::is_utf8($value);
1050              
1051             # There was a Perl bug where looks_like_number() provoked a warning from
1052             # BigRat.pm if it is called under 'use bigrat;' so we must not do that.
1053             # https://github.com/Perl/perl5/issues/20685
1054             #return 0 unless looks_like_number($value);
1055              
1056             # JSON::PP uses these tricks:
1057             # string & "" -> "" # bitstring AND, truncating to shortest operand
1058             # number & "" -> 0 (with warning)
1059             # number * 0 -> 0 unless number is nan or inf
1060              
1061             # Attempt uniary & with "string" and see what happens
1062 3993         6935 my $uand_str_result = eval {
1063 9     9   80 use warnings "FATAL" => "all"; # Convert warnings into exceptions
  9         23  
  9         1016  
1064             # 'bitwise' is the default only in newer perls. So disable.
1065             BEGIN {
1066 9     9   36 eval { # "no feature 'bitwise'" won't compile on Perl 5.20
1067 9         390 feature->unimport( 'bitwise' );
1068 9         144 warnings->unimport("experimental::bitwise");
1069             };
1070 9         298 $@ = "";
1071             }
1072 9     9   63 no warnings "once";
  9         56  
  9         9414  
1073             # Use FF... so we can see what $value was in debug messages below
1074 3993         46894 my $dummy = ($value & "\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}\x{FF}");
1075             };
1076 3993 50       104835 btw '##_san $value \$@=$@' if $Debug;
1077 3993 100 100     10145 if ($@) {
    100          
1078 3019 50       18104 if ($@ =~ /".*" isn't numeric/) {
1079 3019         8900 return 1; # Ergo $value must be numeric
1080             }
1081 0 0       0 if ($@ =~ /\& not supported/) {
1082             # If it is an object then it probably (but not necessarily)
1083             # is numeric but just doesn't support bitwise operators,
1084             # for example BigRat.
1085 0 0       0 return 1 if defined blessed($value);
1086             }
1087 0 0       0 if ($@ =~ /no method found/) { # overloaded but does not do '&'
1088             # It must use overloads, but does not implement '&'
1089             # Assume it is string-ish
1090 0 0       0 return 0 if defined blessed($value); # else our mistake, isn't overloaded
1091             }
1092 0 0       0 warn "# ".__PACKAGE__." : value=",_dbshow($value),
1093             "\n Unhandled warn/exception from unary & :$@\n"
1094             if $Debug;
1095             # Unknown problem, treat as a string
1096 0         0 return 0;
1097             }
1098             elsif (ref($uand_str_result) ne "" && $uand_str_result =~ /NaN|Inf/) {
1099             # unary & returned an object representing Nan or Inf
1100             # (e.g. Math::BigFloat) so $value must be numberish.
1101 140         2800 return 1;
1102             }
1103 834 50       2422 warn "# ".__PACKAGE__." : (value & \"...\") succeeded\n",
1104             " value=", _dbshow($value), "\n",
1105             " uand_str_result=", _dbvis($uand_str_result),"\n"
1106             if $Debug;
1107             # Sigh. With Perl 5.32 (at least) $value & "..." stringifies $value
1108             # or so it seems.
1109 834 100       2263 if (blessed($value)) {
1110             # +42 might throw if object is not numberish e.g. a DateTime
1111 28 50       49 if (blessed(eval{ $value + 42 })) {
  28         83  
1112 28 50       20836 warn " Object and value+42 is still an object, so probably numberish\n"
1113             if $Debug;
1114 28         150 return 1
1115             } else {
1116 0 0       0 warn " Object and value+42 is NOT an object, so it must be stringish\n"
1117             if $Debug;
1118 0         0 return 0
1119             }
1120             } else {
1121 806 50       1456 warn " NOT an object, so must be a string\n",
1122             if $Debug;
1123 806         1870 return 0;
1124             }
1125             }# _show_as_number
1126              
1127             # Split keys into "components" (e.g. 2_16.A has 3 components) and sort
1128             # components containing only digits numerically.
1129             sub __sortkeys {
1130 1118     1118   7712 my $hash = shift;
1131             my $r = [
1132 1118         5217 sort { my @a = split /(?<=\d)(?=\D)|(?<=\D)(?=\d)/,$a;
  4510         22570  
1133 4510         25156 my @b = split /(?<=\d)(?=\D)|(?<=\D)(?=\d)/,$b;
1134 4510         10120 for (my $i=0; $i <= $#a; ++$i) {
1135 4008 100       7500 return 1 if $i > $#b; # a is longer
1136 3718 50 33     10713 my $r = ($a[$i] =~ /^\d+$/ && $b[$i] =~ /^\d+$/)
1137             ? ($a[$i] <=> $b[$i]) : ($a[$i] cmp $b[$i]) ;
1138 3718 50       10051 return $r if $r != 0;
1139             }
1140 502 50       1514 return -1 if $#a < $#b; # a is shorter
1141 0         0 return 0;
1142             }
1143             keys %$hash
1144             ];
1145 1118         12475 $r
1146             }
1147              
1148             my $balanced_re = RE_balanced(-parens=>'{}[]()');
1149              
1150             # cf man perldata
1151             my $userident_re = qr/ (?: (?=\p{Word})\p{XID_Start} | _ )
1152             (?: (?=\p{Word})\p{XID_Continue} )* /x;
1153              
1154             my $pkgname_re = qr/ ${userident_re} (?: :: ${userident_re} )* /x;
1155              
1156             our $curlies_re = RE_balanced(-parens=>'{}');
1157             our $parens_re = RE_balanced(-parens=>'()');
1158             our $curliesorsquares_re = RE_balanced(-parens=>'{}[]');
1159              
1160             my $anyvname_re =
1161             qr/ ${pkgname_re} | [0-9]+ | \^[A-Z]
1162             | [-+!\$\&\;i"'().,\@\/:<>?\[\]\~\^\\] /x;
1163              
1164             my $anyvname_or_refexpr_re = qr/ ${anyvname_re} | ${curlies_re} /x;
1165              
1166             my $addrvis_re = qr/\<\d+:[\da-fA-F]+\>/;
1167              
1168             sub __unmagic_atom() { # edits $_
1169             ## # FIXME this probably could omit the ([^'"]*?) bc there is never anything
1170             ## # between the open quote and the _MAGIC_NOQUOTES_PFX
1171             ## s/(['"])([^'"]*?)
1172             ## (?:\Q${\_MAGIC_NOQUOTES_PFX}\E)
1173             ## (.*?)(\1)/$2$3/xgs;
1174              
1175 17145     17145   25327 s/(['"])
1176 17145         66804 (?:\Q${\_MAGIC_NOQUOTES_PFX}\E) (.*?)
1177 3160         6186 (\1)/do{ local $_ = $2;
  3160         7229  
1178 3160         5567 s!\\(.)!$1!g; # undo double-quotish backslash escapes
1179 3160         9033 $_ }/xegs;
1180              
1181 17145         28347 s/\Q${\_MAGIC_KEEPQUOTES_PFX}\E//gs;
  17145         36919  
1182             }
1183              
1184             sub __unesc_unicode() { # edits $_
1185 15024 100   15024   36659 if (/^"/) {
1186             # Data::Dumper with Useqq(1) outputs wide characters as hex escapes
1187             # Note that a BOM is the ZERO WIDTH NO-BREAK SPACE character and
1188             # so is considered "Graphical", but we want to see it as hex rather
1189             # than "", and probably any other "Format" category Unicode characters.
1190              
1191 3498         8252 s/
1192             \G (?: [^\\]++ | \\[^x] )*+ \K (?<w> \\x\x{7B} (?<hex>[a-fA-F0-9]+) \x{7D} )
1193             /
1194 9     9   32370 my $orig = $+{w};
  9         3732  
  9         911  
  312         1278  
1195 312 100       1688 local $_ = hex( length($+{hex}) > 6 ? '0' : $+{hex} );
1196 312 100       908 $_ = $_ > 0x10FFFF ? "\0" : chr($_); # 10FFFF is Unicode limit
1197             # Using 'lc' so regression tests do not depend on Data::Dumper's
1198             # choice of case when escaping wide characters.
1199 312 100 66     2504 (m<\P{XPosixGraph}|[\0-\177]>
1200             || m<\p{General_Category=Format}>) ? lc($orig) : $_
1201             /xesg;
1202             }
1203             }
1204              
1205             sub __change_quotechars($) { # edits $_
1206 1653 50   1653   8242 if (s/^"//) {
1207 1653 50       8216 oops unless s/"$//;
1208 1653         7985 s/\\"/"/g;
1209 1653 50       6638 my ($l, $r) = split //, $_[0]; oops unless $r;
  1653         4693  
1210 1653         34782 s/([\Q$l$r\E])/\\$1/g;
1211 1653         7744 $_ = "qq".$l.$_.$r;
1212             }
1213             }
1214              
1215             my %qqesc2controlpic = (
1216 9     9   15513 '\0' => "\N{SYMBOL FOR NULL}",
  9         24  
  9         80  
1217             '\a' => "\N{SYMBOL FOR BELL}",
1218             '\b' => "\N{SYMBOL FOR BACKSPACE}",
1219             '\e' => "\N{SYMBOL FOR ESCAPE}",
1220             '\f' => "\N{SYMBOL FOR FORM FEED}",
1221             '\n' => "\N{SYMBOL FOR NEWLINE}",
1222             '\r' => "\N{SYMBOL FOR CARRIAGE RETURN}",
1223             '\t' => "\N{SYMBOL FOR HORIZONTAL TABULATION}",
1224             );
1225             my %char2controlpic = (
1226             map{
1227             my $cp = $qqesc2controlpic{$_};
1228             my $char = eval(qq("$_")) // die;
1229             die "XX<<$_>> YY<<$char>>" unless length($char) == 1;
1230             ($char => $cp)
1231             } keys %qqesc2controlpic
1232             );
1233             sub __subst_controlpic_backesc() { # edits $_
1234             # Replace '\t' '\n' etc. escapes with "control picture" characters
1235 551 50   551   2579 return unless/^"/;
1236 551         4430 s{ \G (?: [^\\]++ | \\[^0abefnrt] )*+ \K ( \\[abefnrt] | \\0(?![0-7]) )
1237             }{
1238 1623   33     12167 $qqesc2controlpic{$1} // $1
1239             }xesg;
1240             }
1241             sub __subst_spacedots() { # edits $_
1242 0 0   0   0 if (/^"/) {
1243 0         0 s{\N{MIDDLE DOT}}{\N{BLACK LARGE CIRCLE}}g;
1244 0         0 s{ }{\N{MIDDLE DOT}}g;
1245             }
1246             }
1247              
1248             my $indent_unit;
1249              
1250             sub _mycallloc(;@) {
1251 0     0   0 my ($lno, $subcalled) = (caller(1))[2,3];
1252 0 0       0 ":".$lno.(@_ ? _dbavis(@_) : "")." "
1253             }
1254              
1255             use constant {
1256 9         839 _WRAP_ALWAYS => 1,
1257             _WRAP_ALLHASH => 2,
1258 9     9   31862 };
  9         25  
1259 9     9   66 use constant _WRAP_STYLE => (_WRAP_ALLHASH);
  9         19  
  9         953  
1260              
1261             sub _postprocess_DD_result {
1262             (my $self, local $_, my $original) = @_;
1263 9     9   72 no warnings 'recursion';
  9         22  
  9         35805  
1264             my ($debug, $listform, $foldwidth, $foldwidth1)
1265             = @$self{qw/Debug _Listform Foldwidth Foldwidth1/};
1266             my $useqq = $self->Useqq();
1267             my $unesc_unicode = $useqq =~ /utf|unic/;
1268             my $controlpics = $useqq =~ /pic/;
1269             my $spacedots = $useqq =~ /space/;
1270             my $qq = $useqq =~ /qq(?:=(..))?/ ? ($1//'{}') : '';
1271             my $pad = $self->Pad() // "";
1272              
1273             $indent_unit = 2; # make configurable?
1274              
1275             my $maxlinelen = $foldwidth1 || $foldwidth || INT_MAX;
1276             my $maxlineNlen = ($foldwidth // INT_MAX) - length($pad);
1277              
1278             if ($debug) {
1279             our $_dbmaxlen = INT_MAX;
1280             btw "## DD result: fw1=",u($foldwidth1)," fw=",u($foldwidth)," pad='${pad}' maxll=$maxlinelen maxlNl=$maxlineNlen\n result=",_dbrawstr($_);
1281             }
1282              
1283             my $top = { tlen => 0, children => [] };
1284             my $context = $top;
1285             my $prepending = "";
1286              
1287             my sub atom($;$) {
1288             (local $_, my $mode) = @_;
1289             $mode //= "";
1290              
1291             __unmagic_atom ;
1292             __unesc_unicode if $unesc_unicode;
1293             __subst_controlpic_backesc if $controlpics;
1294             __subst_spacedots if $spacedots;
1295             __change_quotechars($qq) if $qq;
1296              
1297             if ($prepending) { $_ = $prepending . $_; $prepending = ""; }
1298              
1299             btw "###atom",_mycallloc(), _dbrawstr($_),"($mode)"
1300             ,"\n context:",_dbvisnew($context)->Sortkeys(sub{[grep{exists $_[0]->{$_}} qw/O C tlen children CLOSE_AFTER_NEXT/]})->Dump()
1301             if $debug;
1302             if ($mode eq "prepend_to_next") {
1303             $prepending .= $_;
1304             } else {
1305             if ($mode eq "") {
1306             push @{ $context->{children} }, $_;
1307             }
1308             elsif ($mode eq "open") {
1309             my $child = {
1310             O => $_,
1311             tlen => 0, # incremented below
1312             children => [],
1313             C => undef,
1314             parent => $context,
1315             };
1316             weaken( $child->{parent} );
1317             push @{ $context->{children} }, $child;
1318             $context = $child;
1319             }
1320             elsif ($mode eq "close") {
1321             oops if defined($context->{C});
1322             $context->{C} = $_;
1323             $context->{tlen} += length;
1324             $context = $context->{parent}; # undef if closing the top item
1325             }
1326             elsif ($mode eq "append_to_prev") {
1327             my $prev = $context;
1328             { #block for 'redo'
1329             oops "No previous!" unless @{$prev->{children}} > 0;
1330             if (ref($prev->{children}->[-1] // oops)) {
1331             $prev = $prev->{children}->[-1];
1332             if (! $prev->{C}) { # empty or not-yet-read closer?
1333             redo; # ***
1334             }
1335             $prev->{C} .= $_;
1336             } else {
1337             $prev->{children}->[-1] .= $_;
1338             }
1339             }
1340             }
1341             else {
1342             oops "mode=",_dbvis($mode);
1343             }
1344             my $c = $context;
1345             while(defined $c) {
1346             $c->{tlen} += length($_);
1347             $c = $c->{parent};
1348             }
1349             if ($context->{CLOSE_AFTER_NEXT}) {
1350             oops(_dbvis($context)) if defined($context->{C});
1351             $context->{C} = "";
1352             $context = $context->{parent};
1353             }
1354             }
1355             }#atom
1356              
1357             my sub fat_arrow($) { # =>
1358             my $lhs = $context->{children}->[-1] // oops;
1359             oops if ref($lhs);
1360             my $newchild = {
1361             O => "",
1362             tlen => length($lhs),
1363             children => [ $lhs ],
1364             C => undef,
1365             parent => $context,
1366             };
1367             weaken($newchild->{parent});
1368             $context->{children}->[-1] = $newchild;
1369             $context = $newchild;
1370             atom($_[0]); # the " => "
1371             oops unless $context == $newchild;
1372             $context->{CLOSE_AFTER_NEXT} = 1;
1373             }
1374              
1375             # There is a trade-off between compactness (e.g. want a single line when
1376             # possible), and ease of reading large structures.
1377             #
1378             # At any nesting level, if everything (including any nested levels) fits
1379             # on a single line, then that part is output without folding;
1380             #
1381             # 4/25/2023: Now controlled by constant _WRAP_STYLE:
1382             #
1383             # (_WRAP_STYLE == _WRAP_ALWAYS):
1384             # If folding is necessary, then *every* member of the folded block
1385             # appears on a separate line, so members all vertically align.
1386             #
1387             # *(_WRAP_STYLE & _WRAP_ALLHASH): Members of a hash (key => value)
1388             # are shown on separate lines, but not members of an array.
1389             #
1390             # Otherwise:
1391             #
1392             # When folding is necessary, every member appears on a separate
1393             # line if ANY of them will not fit on a single line; however if
1394             # they all fit individually, then shorter members will be run
1395             # together on the same line. For example:
1396             #
1397             # [aaa,bbb,[ccc,ddd,[eee,fff,hhhhhhhhhhhhhhhhhhhhh,{key => value}]]]
1398             #
1399             # might be shown as
1400             # [ aaa,bbb, # N.B. space inserted before aaa to line up with next level
1401             # [ ccc,ddd, # packed because all siblings fit individually
1402             # [eee,fff,hhhhhhhhhhhhhhhhhhhhh,{key => value}] # entirely fits
1403             # ]
1404             # ]
1405             # but if Foldwidth is smaller then like this:
1406             # [ aaa,bbb,
1407             # [ ccc, # sibs vertically-aligned because not all of them fit
1408             # ddd,
1409             # [ eee,fff, # but within this level, all siblings fit
1410             # hhhhhhhhhhhhhhhhhhhhh,
1411             # {key => value}
1412             # ]
1413             # ]
1414             # ]
1415             # or if Foldwidth is very small then:
1416             # [ aaa,
1417             # bbb,
1418             # [ ccc,
1419             # ddd,
1420             # [ eee,
1421             # fff,
1422             # hhhhhhhhhhhhhhhhhhhhh,
1423             # { key
1424             # =>
1425             # value
1426             # }
1427             # ]
1428             # ]
1429             # ]
1430             #
1431             # Note: Indentation is done regardless of Foldwidth, so deeply nested
1432             # structures may extend beyond Foldwidth even if all elements are short.
1433              
1434             my $outstr;
1435             my $linelen;
1436             our $level;
1437             my sub expand_children($) {
1438             my $parent = shift;
1439             # $level is already set appropriately for $parent->{children},
1440             # and the parent's {opener} is at the end of $outstr.
1441             #
1442             # Intially we are called with a fake parent ($top) containing
1443             # no {opener} and the top-most item as its only child, with $level==0;
1444             # this puts the top item at the left margin.
1445             #
1446             # If all children individually fit then run them all together,
1447             # wrapping only between siblings; otherwise start each sibling on
1448             # it's own line so they line up vertically.
1449             # [4/25/2023: Now controlled by _WRAP_STYLE]
1450              
1451             my $available = $maxlinelen - $linelen;
1452             my $indent_width = $level * $indent_unit;
1453              
1454             my $run_together =
1455             (_WRAP_STYLE & _WRAP_ALWAYS)==0
1456             &&
1457             all{ (ref() ? $_->{tlen} : length) <= $available } @{$parent->{children}}
1458             ;
1459              
1460             if (!$run_together
1461             && @{$parent->{children}}==3
1462             && !ref(my $item=$parent->{children}->[1])) {
1463             # Concatenate (key,=>) if possible
1464             if ($item =~ /\A *=> *\z/) {
1465             $run_together = 1;
1466             btw "# (level $level): Running together $parent->{children}->[0] => value" if $debug;
1467             }
1468             }
1469              
1470             my $indent = ' ' x $indent_width;
1471              
1472             btw "###expand",_mycallloc(), "level $level, avail=$available",
1473             " rt=",_tf($run_together),
1474             " indw=$indent_width ll=$linelen maxll=$maxlinelen : ",
1475             #"{ tlen=",$parent->{tlen}," }",
1476             " p=",_dbvisnew($parent)->Sortkeys(sub{[grep{exists $_[0]->{$_}} qw/O C tlen CLOSE_AFTER_NEXT/]})->Dump(),
1477             "\n os=",_dbstr($outstr) if $debug;
1478              
1479             #oops(_dbavis($linelen,$indent_width)) unless $linelen >= $indent_width;
1480              
1481             my $first = 1;
1482             for my $child (@{$parent->{children}}) {
1483             my $child_len = ref($child) ? $child->{tlen} : length($child);
1484             my $fits = ($child_len <= $available) || 0;
1485              
1486             if ($first) {
1487             } else {
1488             if(!$fits && !ref($child)) {
1489             if ($child =~ /( +)\z/ && ($child_len-length($1)) <= $available) {
1490             # remove trailing space(s) e.g. in ' => '
1491             substr($child,-length($1),INT_MAX,"");
1492             $child_len -= length($1);
1493             oops unless $child_len <= $available;
1494             $fits = 2;
1495             btw "# (level $level): Chopped ",_dbstr($1)," from child" if $debug;
1496             }
1497             if (!$fits && $linelen <= $indent_width && $run_together) {
1498             # If we wrap we'll end up at the same or worse position after
1499             # indenting, so don't bother wrapping if running together
1500             $fits = 3;
1501             btw "# (level $level): Wrap would not help" if $debug
1502             }
1503             }
1504             if (!$fits || !$run_together) {
1505             # start a second+ line
1506             $outstr =~ s/ +\z//;
1507             $outstr .= "\n$indent";
1508             $linelen = $indent_width;
1509             $maxlinelen = $maxlineNlen;
1510              
1511             # elide any initial spaces after wrapping, e.g. in " => "
1512             $child =~ s/^ +// unless ref($child);
1513              
1514             $available = $maxlinelen - $linelen;
1515             $child_len = ref($child) ? $child->{tlen} : length($child);
1516             $fits = ($child_len <= $available);
1517             btw "# (level $level): 2nd+ Pre-WRAP; ",_dbstr($child)," cl=$child_len av=$available ll=$linelen f=$fits rt=",_tf($run_together)," os=",_dbstr($outstr) if $debug;
1518             } else {
1519             btw "# (level $level): (no 2nd+ pre-wrap); ",_dbstr($child)," cl=$child_len av=$available ll=$linelen f=$fits rt=",_tf($run_together) if $debug;
1520             }
1521             }
1522              
1523             if (ref($child)) {
1524             ++$level;
1525             $outstr .= $child->{O};
1526             $linelen += length($child->{O});
1527             if (! $fits && $child->{O} ne "") {
1528             # Wrap before first child, if there is a real opener (not for '=>')
1529             $outstr =~ s/ +\z//;
1530             $outstr .= "\n$indent" . (' ' x $indent_unit);
1531             $linelen = $indent_width + $indent_unit;
1532             $maxlinelen = $maxlineNlen;
1533             btw "# (l $level): Wrap after opener: os=",_dbstr($outstr) if $debug;
1534             }
1535             __SUB__->($child);
1536             if (! $fits && $child->{O} ne "") {
1537             # Wrap before closer if we wrapped after opener
1538             $outstr =~ s/ +\z//;
1539             $outstr .= "\n$indent";
1540             $linelen = $indent_width;
1541             $maxlinelen = $maxlineNlen;
1542             btw "# (l $level): Wrap after closer; ll=$linelen os=",_dbstr($outstr) if $debug;
1543             }
1544             $outstr .= $child->{C};
1545             $linelen += length($child->{C});
1546             --$level;
1547             } else {
1548             $outstr .= $child;
1549             $linelen += length($child);
1550             btw "# (level $level): appended SCALAR ",_dbstr($child)," os=",_dbstr($outstr) if $debug;
1551             }
1552             $available = $maxlinelen - $linelen;
1553             $first = 0;
1554             }
1555             }#expand_children
1556              
1557             # Remove the magic wrapper created by _prefix_refaddr(). The original $ref
1558             # was replaced by
1559             #
1560             # [ _MAGIC_REFADDR.addrvis($ref), $ref, _MAGIC_ELIDE_NEXT, ];
1561             #
1562             # Data::Dumper formatted the magic* items as "quoted strings"
1563             #
1564             s/\[\s*(["'])\Q${\_MAGIC_REFADDR}\E(.*?)\1,\s*/$2/gs;
1565             s/,\s*(["'])\Q${\_MAGIC_ELIDE_NEXT}\E\1,?\s*\]//gs
1566             && $debug && btw "Unwrapped addrvis:",_dbvis($_);
1567              
1568             while ((pos()//0) < length) {
1569             if (/\G[\\\*\!]/gc) { atom($&, "prepend_to_next") }
1570             elsif (/\G[,;]/gc) { atom($&, "append_to_prev") }
1571             elsif (/\G"(?:[^"\\]++|\\.)*+"/gsc) { atom($&) } # "quoted"
1572             elsif (/\G'(?:[^'\\]++|\\.)*+'/gsc) { atom($&) } # 'quoted'
1573             elsif (m(\Gqr/(?:[^\\\/]++|\\.)*+/[a-z]*)gsc){ # Regexp
1574             local $_ = $&;
1575             # Data::Dumper just stringifies a compiled regex, and Perl (v5.34)
1576             # does not stringify actual tab as \t etc. probably because the result
1577             # would be ambiguous if preceeded by another backslash, e.g.
1578             # \<tab> -> \\t would be wrong (backslash character + 't').
1579             #
1580             # If 'controlpics' is enabled, they are always substituted and then
1581             # a preceding backslash is not a problem; otherwise \-escapes are
1582             # substituted only if not preceded by another backslash.
1583             if ($controlpics) {
1584             s{([\x{0}\a\b\e\f\n\r\t])}{ $char2controlpic{$1} // $1 }esg;
1585             } else {
1586             if (/[\x{0}\a\b\e\f\n\r\t]/) {
1587             s/(?<!\\)\x{0}/\\0/g;
1588             s/(?<!\\)[\b]/\N{SYMBOL FOR BACKSPACE}/; # Bare \b matches boundaries
1589             s/(?<!\\)\e/\\e/g;
1590             s/(?<!\\)\f/\\f/g;
1591             s/(?<!\\)\x{0A}/\\n/g;
1592             s/(?<!\\)\x{0D}/\\r/g;
1593             s/(?<!\\)\t/\\t/g;
1594             }
1595             }
1596             atom($_)
1597             }
1598             elsif (/\G${addrvis_re}/gsc) { atom($&, "prepend_to_next") }
1599              
1600             # With Deparse(1) the body has arbitrary Perl code, which we can't parse
1601             elsif (/\Gsub\s*${curlies_re}/gc) { atom($&) } # sub{...}
1602              
1603             # $VAR1->[ix] $VAR1->{key} or just $varname
1604             elsif (/\G(?:my\s+)?\$(?:${userident_re}|\s*->\s*|${balanced_re}+)++/gsc) { atom($&) }
1605              
1606             elsif (/\G\b[A-Za-z_][A-Za-z0-9_]*+\b/gc) { atom($&) } # bareword?
1607             elsif (/\G-?\d[\deE\.]*+\b/gc) { atom($&) } # number
1608             elsif (/\G\s*=>\s*/gc) { fat_arrow($&) }
1609             elsif (/\G\s*=(?=[\w\s'"])\s*/gc) { atom($&) }
1610             elsif (/\G:*${pkgname_re}/gc) { atom($&) }
1611             elsif (/\G[\[\{\(]/gc) { atom($&, "open") }
1612             elsif (/\G[\]\}\)]/gc) { atom($&, "close") }
1613             elsif (/\G\s+/sgc) { }
1614             else {
1615             my $remnant = substr($_,pos//0);
1616             Carp::cluck "UNPARSED ",_dbstr(substr($remnant,0,30)."...")," ",_dbstrposn($_,pos()//0),"\nFULL STRING:",_dbstr($_),"\n(Using remainder as-is)\n" ;
1617             atom($remnant);
1618             while (defined $context->{parent}) { atom("", "close"); }
1619             last;
1620             }
1621             }
1622             oops "Dangling prepend ",_dbstr($prepending) if $prepending;
1623              
1624 0     0   0 btw "--------top-------\n",_dbvisnew($top)->Sortkeys(sub{[qw/O C tlen children/]})->Dump,"\n-----------------" if $debug;
1625              
1626             $outstr = "";
1627             $linelen = 0;
1628             $level = 0;
1629             expand_children($top);
1630              
1631             if (index($listform,'a') >= 0) {
1632             # show [...] as (val1,val2,...) array initializer
1633             # Remove any initial Addrvis prefix
1634             $outstr =~ s/\A(?:${addrvis_re})?\[/(/ && $outstr =~ s/\]\z/)/s or oops _dbvis($outstr);
1635             }
1636             elsif (index($listform,'h') >= 0) {
1637             # show {...} as (key => val, ...) hash initializer
1638             $outstr =~ s/\A(?:${addrvis_re})?\{/(/ && $outstr =~ s/\}\z/)/s or oops;
1639             }
1640             elsif (index($listform,'l') >= 0) {
1641             # show as a bare list without brackets
1642             $outstr =~ s/\A(?:${addrvis_re})?[\[\{]// && $outstr =~ s/[\]\}]\z//s or oops;
1643             }
1644              
1645             # Insert user-specified padding after each embedded newline
1646             if ($pad) {
1647             $outstr =~ s/\n\K(?=[^\n])/$pad/g;
1648             }
1649              
1650             $outstr
1651             } #_postprocess_DD_result {
1652              
1653             sub _Interpolate {
1654 1273     1273   3917 my ($self, $input, $i_or_d) = @_;
1655 1273 50       3950 _croak_or_confess $i_or_d."vis('$input') called in void context.\nDid you forget to 'say ...'?"
1656             unless defined wantarray;
1657              
1658 1273 100       3711 return "<undef arg>" if ! defined $input;
1659              
1660 1270         3600 &_SaveAndResetPunct;
1661              
1662 1270         6212 my $debug = $self->Debug;
1663 1270         4417 my $useqq = $self->Useqq;
1664              
1665 1270 100       19630 my $q = $useqq ? "" : "q";
1666 1270         3254 my $funcname = $i_or_d . "vis" .$q;
1667              
1668 1270         2515 my @pieces; # list of [visfuncname or 'p' or 'e', inputstring]
1669 1270         2222 { local $_ = $input;
  1270         2939  
1670 1270 50       4854 if (/\b((?:ARRAY|HASH|SCALAR)\(0x[a-fA-F0-9]+\))/) {
1671 0         0 state $warned=0;
1672 0 0       0 carp("Warning: String passed to $funcname may have been interpolated by Perl\n(use 'single quotes' to avoid this)\n") unless $warned++;
1673             }
1674 1270         3563 while (
1675             /\G (
1676             # Stuff without variable references (might include \n etc. escapes)
1677              
1678             #This gets "recursion limit exceeded"
1679             #( (?: [^\\\$\@\%] | \\[^\$\@\%] )++ )
1680             #|
1681              
1682             (?: [^\\\$\@\%]++ )
1683             |
1684             #(?: (?: \\[^\$\@\%] )++ )
1685             (?: (?: \\. )++ )
1686             |
1687              
1688             # $#arrayvar $#$$...refvarname $#{aref expr} $#$$...{ref2ref expr}
1689             #
1690             (?: \$\#\$*+\K ${anyvname_or_refexpr_re} )
1691             |
1692              
1693             # $scalarvar $$$...refvarname ${sref expr} $$$...{ref2ref expr}
1694             # followed by [] {} ->[] ->{} ->method() ... «zero or more»
1695             # EXCEPT $$<punctchar> is parsed as $$ followed by <punctchar>
1696              
1697             (?:
1698             (?: \$\$++ ${pkgname_re} \K | \$ ${anyvname_or_refexpr_re} \K )
1699             (?:
1700             (?: ->\K(?: ${curliesorsquares_re}|${userident_re}${parens_re}? ))
1701             |
1702             ${curliesorsquares_re}
1703             )*
1704             )
1705             |
1706              
1707             # @arrayvar @$$...varname @{aref expr} @$$...{ref2ref expr}
1708             # followed by [] {} «zero or one»
1709             #
1710 4374         59309 (?: \@\$*+\K ${anyvname_or_refexpr_re} ${$curliesorsquares_re}? )
1711             |
1712             # %hash %$hrefvar %{href expr} %$$...sref2hrefvar «no follow-ons»
1713             (?: \%\$*+\K ${anyvname_or_refexpr_re} )
1714             ) /xsgc)
1715             {
1716 3104 50       31637 local $_ = $1; oops unless length() > 0;
  3104         7430  
1717 3104 100       9169 if (/^[\$\@\%]/) {
1718 1207         3653 my $sigl = substr($_,0,1);
1719 1207 100       3917 if ($i_or_d eq 'd') {
1720             # Inject a "plain text" fragment containing the "expr=" prefix,
1721             # omitting the '$' sigl if the expr is a plain '$name'.
1722 1178 100       10614 push @pieces, ['P', (/^\$(?!_)(${userident_re})\z/ ? $1 : $_)."="];
1723             }
1724 1207 100       6249 if ($sigl eq '$') {
    100          
    50          
1725 939         3610 push @pieces, ["vis", $_];
1726             }
1727             elsif ($sigl eq '@') {
1728 203         885 push @pieces, ["avis", $_];
1729             }
1730             elsif ($sigl eq '%') {
1731 65         270 push @pieces, ["hvis", $_];
1732             }
1733 0         0 else { oops }
1734             }
1735             else {
1736 1897 50       7156 if (/^.+?(?<!\\)([\$\@\%])/) {
1737 0         0 confess __PACKAGE__." bug: Missed '$1' in «$_»"
1738             }
1739             # Due to the need to simplify the big regexp above, \x{abcd} is now
1740             # split into "\x" and "{abcd}". Combine consecutive pass-thrus
1741             # into a single passthru ('p'), converted later to 'e' if an eval
1742             # is needed.
1743 1897 100 100     8844 if (@pieces && $pieces[-1]->[0] eq 'p') {
1744 107         279 $pieces[-1]->[1] .= $_;
1745             } else {
1746 1790         7375 push @pieces, [ 'p', $_ ];
1747             }
1748             }
1749             }
1750 1270 50 33     7351 if (!defined(pos) || pos() < length($_)) {
1751 0   0     0 my $leftover = substr($_,pos()//0);
1752 0         0 my $e;
1753             # Try to recognize user syntax errors
1754 0 0       0 if ($leftover =~ /^[\$\@\%][\s\%\@]/) {
1755 0         0 $e = "Invalid expression syntax starting at '$leftover' in $funcname arg"
1756             } else {
1757             # Otherwise we may have a parser bug
1758 0         0 $e = "Invalid expression (or ".__PACKAGE__." bug):\n«$leftover»";
1759             }
1760 0         0 carp "$e\n";
1761 0         0 push @pieces, ['p',"<INVALID EXPRESSION>".$leftover];
1762             }
1763 1270         3194 foreach (@pieces) {
1764 4175         8607 my ($meth, $str) = @$_;
1765             # If the user uses 'single quoted' strings then backslash escapes
1766             # can not be emulated exactly as they would work in double-quoted strings
1767             # because \ is inconsistently passed through, namely only when not
1768             # followed by another backslash (or a quote character).
1769             # say ivis '\015'; # octal escape for CR intended?
1770             # say ivis '\\015'; # four literal characters \015 intended?
1771             # We can not tell the difference because we get \015 in both cases.
1772             #
1773             # Currently we interpolate all \-escapes we see, so to get a literal
1774             # backslash users must double them, e.g.
1775             # say ivis 'The four char escape sequence \\\\015 produces \015';
1776             # Here-docs do not treat \ specially and so avoid this problem:
1777             # say ivis <<\END;
1778             # The four char escape sequence \\015 produces \015
1779             # END
1780             #
1781             # 0/18/23: Now really *all* \-escapes are interpolated, so this works:
1782             # say ivis '\$foo = $foo' # $foo = <value>
1783              
1784             #next unless $meth eq 'p' && $str =~ /\\[abtnfrexXN0-7]/;
1785             #$str =~ s/([()\$\@\%])/\\$1/g; # dont hide \-escapes to be interpolated!
1786              
1787 4175 100       11601 if ($meth eq 'p') {
    100          
1788 1790 100       6696 if ($str =~ /\\./) {
1789 463         1155 $str =~ s/\$\\/\$\\\\/g; # Assume the punct var $\ is not intended
1790 463         1410 $_->[1] = "qq(" . $str . ")";
1791 463         1427 $_->[0] = 'e';
1792             }
1793             }
1794             elsif ($meth eq 'P') {
1795 1178         2754 $_->[0] = 'p';
1796             }
1797             }
1798             } #local $_
1799              
1800 1270         4539 @_ = ($self, $funcname, \@pieces);
1801 1270         5384 goto &DB::DB_Vis_Interpolate
1802             }
1803              
1804             sub quotekey(_) { # Quote a hash key if not a valid bareword
1805 0 0 0 0 1 0 $_[0] =~ /\A${userident_re}\z/s ? $_[0] :
    0          
    0          
1806             $_[0] =~ /(?!.*')["\$\@]/ ? visq("$_[0]") :
1807             $_[0] =~ /\W/ && !looks_like_number($_[0]) ? vis("$_[0]") :
1808             "\"$_[0]\""
1809             }
1810              
1811             package
1812             DB;
1813              
1814             sub DB_Vis_Interpolate {
1815 1270     1270 0 3410 my ($self, $funcname, $pieces) = @_;
1816 1270         2789 my $result = "";
1817 1270         3117 foreach my $p (@$pieces) {
1818 4175         8547 my ($methname, $arg) = @$p;
1819             #say "III methname=$methname arg='$arg'";
1820 4175 100       9792 if ($methname eq 'p') {
    100          
1821 2505         5569 $result .= $arg;
1822             }
1823             elsif ($methname eq 'e') {
1824 463         1547 $result .= DB::DB_Vis_Eval($funcname, $arg);
1825             } else {
1826             # Reduce width before first wrap to account for stuff already on the line
1827 1207         3783 my $leftwid = length($result) - rindex($result,"\n") - 1;
1828 1207         2904 my $foldwidth = $self->{Foldwidth};
1829 1207   66     5704 local $self->{Foldwidth1} = $self->{Foldwidth1} // $foldwidth;
1830 1207 100       3367 if ($foldwidth) {
1831             $self->{Foldwidth1} -= $leftwid if $leftwid < $self->{Foldwidth1}
1832 1121 50       3729 }
1833 1207         3405 $result .= $self->$methname( DB::DB_Vis_Eval($funcname, $arg) );
1834             }
1835             }
1836              
1837 1270         4336 &Data::Dumper::Interp::_RestorePunct; # saved in _Interpolate
1838 1270         24764 $result
1839             }# DB_Vis_Interpolate
1840              
1841             # eval a string in the user's context and return the result. The nearest
1842             # non-DB frame must be the original user's call; this is accomplished by
1843             # dvis(), and friends using "goto &_Interpolate", which in turn
1844             # does "goto &DB::DB_Vis_Interpolate" to enter package DB.
1845             sub DB_Vis_Eval($$) {
1846 1670     1670 0 4023 my ($label_for_errmsg, $evalarg) = @_;
1847 1670 50       4170 Carp::confess("Data::Dumper::Interp bug:empty evalarg") if $evalarg eq "";
1848             # Inspired perl5db.pl but at this point has been rewritten
1849              
1850             # Find the closest non-DB caller. The eval will be done in that package.
1851             # Find the next caller further up which has arguments (i.e. wasn't doing
1852             # "&subname;"), and make @_ contain those arguments.
1853 1670         3273 my ($distance, $pkg, $fname, $lno);
1854 1670         3293 for ($distance = 0 ; ; $distance++) {
1855 3340         105480 ($pkg, $fname, $lno) = caller($distance);
1856 3340 100       16709 last if $pkg ne "DB";
1857             }
1858 1670         4956 local *_ = [];
1859 1670         2990 while() {
1860 3305         5099 $distance++;
1861 3305         18635 my ($p, $hasargs) = (caller($distance))[0,4];
1862 3305 100       11095 if (! defined $p){
1863 45         122 *_ = [ '<@_ is not defined in the outer block>' ];
1864             last
1865 45         83 }
1866 3260 100       7157 if ($hasargs) {
1867 1625         4882 *_ = [ @DB::args ]; # copy in case of recursion
1868             last
1869 1625         3452 }
1870             }
1871              
1872 1670         2568 my @result = do {
1873 1670         3392 local @Data::Dumper::Interp::result;
1874 1670         6824 local $Data::Dumper::Interp::string_to_eval =
1875             "package $pkg; "
1876             # N.B. eval first clears $@ so we must restore $@ inside the eval
1877             .' &Data::Dumper::Interp::_RestorePunct_NoPop;' # saved in _Interpolate
1878             # In case something carps or croaks (e.g. because of ${\(somefunc())}
1879             # or a tie handler), force a full backtrace so the user's call location
1880             # is visible. Unfortunately there is no way to make carp() show only
1881             # the location of the user's call because we must force the eval'd
1882             # string into in e.g. package main so user functions can be found.
1883             .' local $Carp::Verbose = 1;'
1884             .' @Data::Dumper::Interp::result = '.$evalarg.';'
1885             .' $Data::Dumper::Interp::save_stack[-1]->[0] = $@;' # possibly changed by a tie handler
1886             ;
1887             ###??? FIXME why is DB_Vis_Evalwrapper needed? Lexical scope?
1888 1670         4517 &DB_Vis_Evalwrapper;
1889             @Data::Dumper::Interp::result
1890 1670         13371 };
1891 1670         3959 my $errmsg = $@;
1892              
1893 1670 50       4428 if ($errmsg) {
1894 0         0 $errmsg = Data::Dumper::Interp::_chop_ateval($errmsg);
1895 0         0 Carp::carp("${label_for_errmsg} interpolation error: $errmsg\n");
1896 0 0       0 @result = ( (defined($result[0]) ? $result[0] : "")."<invalid/error>" );
1897             }
1898              
1899 1670 50       35230 wantarray ? @result : (do{die "bug" if @result>1}, $result[0])
  463 100       3831  
1900             }# DB_Vis_Eval
1901              
1902             1;
1903             __END__
1904              
1905             =pod
1906              
1907             =encoding UTF-8
1908              
1909             =head1 NAME
1910              
1911             Data::Dumper::Interp - interpolate Data::Dumper output into strings for human consumption
1912              
1913             =head1 SYNOPSIS
1914              
1915             use open IO => ':locale';
1916             use Data::Dumper::Interp;
1917              
1918             @ARGV = ('-i', '/file/path');
1919             my %hash = (abc => [1,2,3,4,5], def => undef);
1920             my $ref = \%hash;
1921             my $obj = bless {}, "Foo::Bar";
1922              
1923             # Interpolate variables in strings with Data::Dumper output
1924             say ivis 'FYI ref is $ref\nThat hash is: %hash\nArgs are @ARGV';
1925              
1926             # -->FYI ref is {abc => [1,2,3,4,5], def => undef}
1927             # That hash is: (abc => [1,2,3,4,5], def => undef)
1928             # Args are ("-i","/file/path")
1929              
1930             # Label interpolated values with "expr="
1931             say dvis '$ref\nand @ARGV';
1932              
1933             # -->ref={abc => [1,2,3,4,5], def => undef}
1934             # and @ARGV=("-i","/file/path")
1935              
1936             # Functions to format one thing
1937             say vis $ref; #prints {abc => [1,2,3,4,5], def => undef}
1938             say vis \@ARGV; #prints ["-i", "/file/path"] # any scalar
1939             say avis @ARGV; #prints ("-i", "/file/path")
1940             say hvis %hash; #prints (abc => [1,2,3,4,5], def => undef)
1941              
1942             # Format a reference with abbreviated referent address
1943             say visr $href; #prints HASH<457:1c9>{abc => [1,2,3,4,5], ...}
1944              
1945             # Just abbreviate a referent address or arbitrary number
1946             say addrvis refaddr($ref); # 457:1c9
1947             say addrvis $ref; # HASH<457:1c9>
1948             say addrvis $obj; # Foo::Bar<984:ef8>
1949              
1950             # Stringify objects
1951             { use bigint;
1952             my $struct = { debt => 999_999_999_999_999_999.02 };
1953             say vis $struct;
1954             # --> {debt => (Math::BigFloat)999999999999999999.02}
1955              
1956             # But if you do want to see object internals...
1957             #
1958             say visnew->Objects(0)->vis($struct);
1959             # --> {debt => bless({...lots of stuff...},'Math::BigInt')}
1960              
1961             # or, equivalently
1962             { local $Data::Dumper::Interp::Objects=0; say vis $struct; }
1963              
1964             # yet another equivalent way
1965             say viso $struct; # not exported by default
1966             }
1967              
1968             # Wide characters are readable
1969             use utf8;
1970             my $h = {msg => "My language is not ASCII ☻ ☺ 😊 \N{U+2757}!"};
1971             say dvis '$h' ;
1972             # --> h={msg => "My language is not ASCII ☻ ☺ 😊 ❗"}
1973              
1974             #-------- OO API --------
1975              
1976             say Data::Dumper::Interp->new()
1977             ->MaxStringwidth(50)->Maxdepth($levels)->vis($datum);
1978              
1979             say visnew->MaxStringwidth(50)->Maxdepth($levels)->vis($datum);
1980              
1981             #-------- UTILITY FUNCTIONS --------
1982             say u($might_be_undef); # $_[0] // "undef"
1983             say quotekey($string); # quote hash key if not a valid bareword
1984             say qsh($string); # quote if needed for /bin/sh
1985             say qshpath($pathname); # shell quote excepting ~ or ~username prefix
1986             say "Runing this: ", qshlist(@command_and_args);
1987              
1988             system "ls -ld ".join(" ",map{ qshpath }
1989             ("/tmp", "~sally/My Documents", "~"));
1990              
1991              
1992             =head1 DESCRIPTION
1993              
1994             This Data::Dumper wrapper optimizes output for human consumption
1995             and avoids side-effects which interfere with debugging.
1996              
1997             The namesake feature is interpolating Data::Dumper output
1998             into strings, but simple functions are also provided
1999             to format a scalar, array, or hash.
2000              
2001             Internally, Data::Dumper is called to visualize (i.e. format) data
2002             with pre- and post-processing to "improve" the results:
2003              
2004             =over 2
2005              
2006             =item * Output is 1 line if possible,
2007             otherwise folded at your terminal width, WITHOUT a trailing newline.
2008              
2009             =item * Printable Unicode characters appear as themselves.
2010              
2011             =item * Object internals are not shown by default; Math:BigInt etc. are stringified.
2012              
2013             =item * "virtual" values behind overloaded deref operators are shown.
2014              
2015             =item * Data::Dumper bugs^H^H^H^Hquirks are circumvented.
2016              
2017             =back
2018              
2019             See "DIFFERENCES FROM Data::Dumper".
2020              
2021             A few utilities are also provided to quote strings for /bin/sh.
2022              
2023             =head1 FUNCTIONS
2024              
2025             =head2 ivis 'string to be interpolated'
2026              
2027             Returns the argument with variable references and escapes interpolated
2028             as in in Perl double-quotish strings, but using Data::Dumper to
2029             format variable values.
2030              
2031             C<$var> is replaced by its value,
2032             C<@var> is replaced by "(comma, sparated, list)",
2033             and C<%hash> by "(key => value, ...)" .
2034             Complex expressions with indexing, dereferences, slices
2035             and method calls are also recognized.
2036              
2037             Expressions are evaluated in the caller's context using Perl's debugger
2038             hooks, and may refer to almost any lexical or global visible at
2039             the point of call (see "LIMITATIONS").
2040              
2041             IMPORTANT: The argument must be single-quoted to prevent Perl
2042             from interpolating it beforehand.
2043              
2044             =head2 dvis 'string to be interpolated'
2045              
2046             Like C<ivis> but interpolations are prefixed with a "expr=" label
2047             and spaces are shown visibly as '·'.
2048              
2049             The 'd' in 'dvis' stands for B<d>ebugging messages, a frequent use case where
2050             brevity of typing is needed.
2051              
2052             =head2 vis [SCALAREXPR]
2053              
2054             =head2 avis LIST
2055              
2056             =head2 hvis EVENLIST
2057              
2058             C<vis> formats a single scalar ($_ if no argument is given)
2059             and returns the resulting string.
2060              
2061             C<avis> formats an array (or any list) as comma-separated values in parenthesis.
2062              
2063             C<hvis> formats key => value pairs in parenthesis.
2064              
2065             =head2 FUNCTION (and METHOD) VARIATIONS
2066              
2067             Variations of the above five functions have extra characters
2068             in their names to imply certain options.
2069             For example C<visq> is like C<vis> but
2070             shows strings in single-quoted form (implied by the 'B<q>' suffix).
2071              
2072             There are no fixed function names; you can use any combination of
2073             characters in any order, prefixed or suffixed to the primary name
2074             with optional '_' separators.
2075             The function will be I<generated> when it is imported* or called as a method.
2076              
2077             The available modifier characters are:
2078              
2079             =over 2
2080              
2081             B<l> - omit parenthesis to return a bare list (only with "avis" or "hvis")
2082              
2083             B<o> - show object internals
2084              
2085             =over
2086              
2087             Calling B<< Objects(0) >> using the OO api has the same effect.
2088              
2089             =back
2090              
2091             B<q> - show strings 'single quoted' if possible
2092              
2093             =over
2094              
2095             Internally, Data::Dumper is called with C<Useqq(0)>, but depending
2096             on the version of Data::Dumper the result may be "double quoted"
2097             anyway if wide characters are present.
2098              
2099             =back
2100              
2101             B<r> - show abbreviated addresses of objects and other refs
2102              
2103             =over
2104              
2105             Calling B<< Reftype(1) >> using the OO api has the same effect.
2106              
2107             =back
2108              
2109             B<NUMBER> - limit nested structure depth to NUMBER levels
2110              
2111             =over
2112              
2113             Calling B<< Maxdepth(NUMBER) >> using the OO api has the same effect.
2114              
2115             =back
2116              
2117             =back
2118              
2119             If you call a function directly it must be explicitly listed
2120             in the C<< S<use Data::Dumper::Interp ... ;> >> statement
2121             unless it is imported by default (list shown below)
2122             or created via the :all tag.
2123              
2124             To avoid having to specify functions in advance, you can
2125             use them as methods and import only the C<visnew> function:
2126              
2127             use Spreadsheet::Edit::Interp qw/visnew/;
2128             ...
2129             say visnew->vis($struct);
2130             say visnew->visrq($my_object);
2131             say visnew->avis(@ARGV);
2132             say visnew->avis2lrq(@ARGV);
2133             etc.
2134              
2135             (C<visnew> creates a new object. Non-existent methods are auto-generated when
2136             first called via the AUTOLOAD mechanism).
2137              
2138             =head2 Functions imported by default
2139              
2140             ivis dvis vis avis hvis
2141              
2142             ivisq dvisq visq avisq hvisq rvis rvisq
2143              
2144             visnew
2145             addrvis addrvisl
2146             u quotekey qsh qshlist qshpath
2147              
2148             =head2 The :all import tag
2149             Z<> Z<>
2150              
2151             use Data::Dumper::Interp qw/:all/;
2152              
2153             This generates and imports all possible variations (with NUMBER <= 2).
2154             that have suffix characters in alphabetical order, without underscores.
2155             There are 119 variations, too many to remember.
2156              
2157             But you only really need to remember the five standard names
2158              
2159             ivis, dvis, vis, avis, and hvis
2160              
2161             and the possible suffixes and their order (I<NUMBER>,l,o,q,r).
2162              
2163             For example, one function is C<avis2lq>, which
2164              
2165             * Formats multiple arguments as an array ('avis')
2166             * Decends at most 2 levels into structures ('2')
2167             * Returns a comma-separated list *without* parenthesis ('l')
2168             * Shows strings in single-quoted form ('q')
2169              
2170             You could equally well have made up different names like C<avis2ql>,
2171             C<q2avisl>, C<q_2_avis_l> etc.
2172             for the same function if you explicitly imported those alternate
2173             names or called them as methods.
2174              
2175             * To save memory, only stub declarations for prototype
2176             checking are generated for imported functions.
2177             The body will be generated when a function is actually used
2178             via the AUTOLOAD mechanism. The C<:debug> import tag
2179             prints messages as these events occur.
2180              
2181             =head1 Showing Abbreviated Addresses
2182              
2183             =head2 addrvis REF_or_NUMBER
2184              
2185             This function returns a string showing an address in both decimal and
2186             hexadecimal, but abbreviated to only the last few digits.
2187              
2188             The number of digits starts at 3 and increases over time if necessary
2189             to keep new results unambiguous.
2190              
2191             For REFs, the result is like I<< "HASHE<lt>457:1c9E<gt>" >>
2192             or, for blessed objects, I<< "Package::NameE<lt>457:1c9E<gt>" >>.
2193              
2194             If the argument is a plain number, just the abbreviated decimal:hex address
2195             is returned, e.g. I<< "E<lt>457:1c9E<gt>" >>.
2196              
2197             I<"undef"> is returned if the argument is undefined.
2198             Croaks if the argument is defined but not a ref.
2199              
2200             C<addrvis_digits(NUMBER)> forces a minimum width
2201             and C<addrvis_forget()> discards past values and resets to 3 digits.
2202              
2203             =head2 addrvisl REF_or_NUMBER
2204              
2205             Like C<addrvis> but omits the <angle brackets>.
2206              
2207             =head1 OBJECT-ORIENTED API
2208              
2209             =head2 Data::Dumper::Interp->new()
2210              
2211             =head2 visnew()
2212              
2213             These create an object initialized from the global configuration
2214             variables listed below. C<visnew> is simply a shorthand wrapper.
2215              
2216             No arguments are permitted.
2217              
2218             B<All the functions described above> including all possible variations
2219             may be called as I<methods> on an object
2220             (when not called as a method the functions create a new object internally).
2221              
2222             For example:
2223              
2224             $msg = visnew->Foldwidth(40)->avis(@ARGV);
2225              
2226             returns the same string as
2227              
2228             local $Data::Dumper::Interp::Foldwidth = 40;
2229             $msg = avis @ARGV;
2230              
2231             Any "variation" can be called, for example
2232              
2233             $msg = visnew->vis_r2($x); # show addresses; Maxdepth 2
2234              
2235             =head1 Configuration Variables / Methods
2236              
2237             These work the same way as variables/methods in Data::Dumper.
2238              
2239             Each config method has a corresponding global variable
2240             in package C<Data::Dumper::Interp> which provides the default value.
2241              
2242             When a config method is called without arguments the current value is returned,
2243             and when called with an argument the value is changed and
2244             the object is returned so that calls can be chained.
2245              
2246             =head2 MaxStringwidth(INTEGER)
2247              
2248             =head2 Truncsuffix("...")
2249              
2250             Longer strings are truncated and I<Truncsuffix> appended.
2251             MaxStringwidth=0 (the default) means no limit.
2252              
2253             =head2 Foldwidth(INTEGER)
2254              
2255             Defaults to the terminal width at the time of first use.
2256              
2257             =head2 Objects(BOOL);
2258              
2259             =head2 Objects("classname")
2260              
2261             =head2 Objects([ list of classnames ])
2262              
2263             A I<false> value disables special handling of objects
2264             (that is, blessed things) and internals are shown as with Data::Dumper.
2265              
2266             A "1" (the default) enables for all objects,
2267             otherwise only for the specified class name(s) [or derived classes].
2268              
2269             When enabled, object internals are never shown.
2270             The class and abbreviated address are shown as with C<addrvis>
2271             e.g. "Foo::Bar<392:0f0>", unless the object overloads
2272             the stringification ('""') operator,
2273             or array-, hash-, scalar-, or glob- deref operators;
2274             in that case the first overloaded operator found will be evaluated,
2275             the object replaced by the result, and the check repeated.
2276              
2277             =head2 Sortkeys(subref)
2278              
2279             The default sorts numeric substrings in keys by numerical
2280             value, e.g. "A.20" sorts before "A.100". See C<Data::Dumper> documentation.
2281              
2282             =head2 Useqq
2283              
2284             0 means generate 'single quoted' strings when possible.
2285              
2286             1 means generate "double quoted" strings as-is from Data::Dumper.
2287             Non-ASCII charcters will be shown as hex escapes.
2288              
2289             Otherwise generate "double quoted" strings enhanced according to option
2290             keywords given as a :-separated list, e.g. Useqq("unicode:controlpics").
2291             The avilable options are:
2292              
2293             =over 4
2294              
2295             =item "unicode"
2296              
2297             Printable ("graphic")
2298             characters are shown as themselves rather than hex escapes, and
2299             '\n', '\t', etc. are shown for ASCII control codes.
2300              
2301             =item "controlpics"
2302              
2303             Show ASCII control characters using single "control picture" characters:
2304             '␤' is shown for newline instead of '\n', and
2305             similarly ␀ ␇ ␈ ␛ ␌ ␍ ␉ for \0 \a \b \e \f \r \t.
2306              
2307             Every character occupies the same space with a fixed-width font, but
2308             the tiny "control picures" can be hard to read;
2309             to see traditional \n etc. while still seeing wide characters as themselves,
2310             set C<Useqq> to just "unicode";
2311              
2312             =item "spacedots"
2313              
2314             Space characters are shown as '·' (Middle Dot).
2315              
2316             =item "qq"
2317              
2318             =item "qq=XY"
2319              
2320             Show using Perl's qq{...} syntax, or qqX...Y if delimiters are specified,
2321             rather than "...".
2322              
2323             =back
2324              
2325             The default is C<Useqq('unicode')> except for
2326             functions/methods with 'q' in their name, which force C<Useqq(0)>.
2327              
2328             =head2 Quotekeys
2329              
2330             =head2 Maxdepth
2331              
2332             =head2 Maxrecurse
2333              
2334             =head2 Deparse
2335              
2336             =head2 Deepcopy
2337              
2338             See C<Data::Dumper> documentation.
2339              
2340             =head1
2341              
2342             =head1 UTILITY FUNCTIONS
2343              
2344             =head2 u
2345              
2346             =head2 u SCALAR
2347              
2348             Returns the argument ($_ by default) if it is defined, otherwise
2349             the string "undef".
2350              
2351             =head2 quotekey
2352              
2353             =head2 quotekey SCALAR
2354              
2355             Returns the argument ($_ by default) if it is a valid bareword,
2356             otherwise a "quoted string".
2357              
2358             =head2 qsh [$string]
2359              
2360             The string ($_ by default) is quoted if necessary for parsing
2361             by the shell (/bin/sh), which has different quoting rules than Perl.
2362             On Win32 quoting is for cmd.com.
2363              
2364             If the string contains only "shell-safe" ASCII characters
2365             it is returned as-is, without quotes.
2366              
2367             If the argument is a ref but is not an object which stringifies,
2368             then vis() is called and the resulting string quoted.
2369             An undefined value is shown as C<undef> without quotes;
2370             as a special case to avoid ambiguity the string 'undef' is always "quoted".
2371              
2372             =head2 qshpath [$might_have_tilde_prefix]
2373              
2374             Similar to C<qsh> except that an initial ~ or ~username is left
2375             unquoted. Useful with bash or csh.
2376              
2377             =head2 qshlist @items
2378              
2379             Format e.g. a shell command and arguments, quoting when necessary.
2380              
2381             Returns a string with the items separated by spaces.
2382              
2383             =head1 LIMITATIONS
2384              
2385             =over 2
2386              
2387             =item Interpolated Strings
2388              
2389             C<ivis> and C<dvis> evaluate expressions in the user's context
2390             using Perl's debugger support ('eval' in package DB -- see I<perlfunc>).
2391             This mechanism has some limitations:
2392              
2393             @_ will appear to have the original arguments to a sub even if "shift"
2394             has been executed. However if @_ is entirely replaced, the correct values
2395             will be displayed.
2396              
2397             A lexical ("my") sub creates a closure, and variables in visible scopes
2398             which are not actually referenced by your code may not exist in the closure;
2399             an attempt to display them with C<ivis> will fail. For example:
2400              
2401             our $global;
2402             sub outerfunc {
2403             my sub inner {
2404             say dvis '$global'; # croaks with "Error interpolating '$global'"
2405             # my $x = $global; # ... unless this is un-commented
2406             }
2407             &inner();
2408             }
2409             &outerfunc;
2410              
2411              
2412             =item Multiply-referenced items
2413              
2414             If a structure contains several refs to the same item,
2415             the first ref will be visualized by showing the referenced item
2416             as you might expect.
2417              
2418             However subsequent refs will look like C<< $VAR1->place >>
2419             where C<place> is the location of the first ref in the overall structure.
2420             This is how Data::Dumper indicates that the ref is a copy of the first
2421             ref and thus points to the same datum.
2422             "$VAR1" is an artifact of how Data::Dumper would generate code
2423             using its "Purity" feature. Data::Dumper::Interp does nothing
2424             special and simply passes through these annotations.
2425              
2426             =item The special "_" stat filehandle may not be preserved
2427              
2428             Data::Dumper::Interp queries the operating
2429             system to obtain the window size to initialize C<$Foldwidth>, if it
2430             is not already defined; this may change the "_" filehandle.
2431             After the first call (or if you pre-set C<$Foldwidth>),
2432             the "_" filehandle will not change across calls.
2433              
2434             =back
2435              
2436             =head1 DIFFERENCES FROM Data::Dumper
2437              
2438             Results differ from plain C<Data::Dumper> output in the following ways
2439             (most substitutions can be disabled via Config options):
2440              
2441             =over 2
2442              
2443             =item *
2444              
2445             A final newline is I<never> included.
2446              
2447             Everything is shown on a single line if possible, otherwise wrapped to
2448             your terminal width (or C<$Foldwidth>), with indented structure levels.
2449              
2450             =item *
2451              
2452             Printable Unicode characters appear as themselves instead of \x{ABCD}.
2453              
2454             Note: If your data contains 'wide characters', you should
2455             C<< use open IO => ':locale'; >> or otherwise arrange to
2456             encode the output for your terminal.
2457             You'll also want C<< use utf8; >> if your Perl source
2458             contains characters outside the ASCII range.
2459              
2460             Undecoded binary octets (e.g. data read from a 'binmode' file)
2461             will still be escaped as individual bytes.
2462              
2463             =item *
2464              
2465             Depending on options, spaces·may·be·shown·visibly
2466             and '␤' may be shown for newline (and similarly for other ASCII controls).
2467              
2468             "White space" characters in qr/compiled regex/ are shown as \t, \n etc.
2469              
2470             =item *
2471              
2472             The internals of objects are not shown by default.
2473              
2474             If stringifcation is overloaded it is used to obtain the object's
2475             representation. For example, C<bignum> and C<bigrat> numbers are shown as easily
2476             readable values rather than S<"bless( {...}, 'Math::...')">.
2477              
2478             Stingified objects are prefixed with "(classname)" to make clear what
2479             happened.
2480              
2481             The "virtual" value of objects which overload a dereference operator
2482             (C<@{}> or C<%{}>) is displayed instead of the object's internals.
2483              
2484             =item *
2485              
2486             Hash keys are sorted treating numeric "components" numerically.
2487             For example "A.20" sorts before "A.100".
2488              
2489             =item *
2490              
2491             Punctuation variables such as $@, $!, and $?, are preserved over calls.
2492              
2493             =item *
2494              
2495             Numbers and strings which look like numbers are kept distinct when displayed,
2496             i.e. "0" does not become 0 or vice-versa. Floating-point values are shown
2497             as numbers not 'quoted strings' and similarly for stringified objects.
2498              
2499             Although such differences might be immaterial to Perl during execution,
2500             they may be important when communicating to a human.
2501              
2502             =back
2503              
2504             =head1 SEE ALSO
2505              
2506             Data::Dumper
2507              
2508             =head1 AUTHOR
2509              
2510             Jim Avera (jim.avera AT gmail)
2511              
2512             =head1 LICENSE
2513              
2514             Public Domain or CC0.
2515              
2516             =for nobody Foldwidth1 is currently an undocumented experimental method
2517             =for nobody which sets a different fold width for the first line only.
2518             =for nobody The Debug method is for author's debugging, and not documented.
2519             =for nobody
2520             =for nobody oops and btw btwN are internal debugging functions
2521              
2522             =for Pod::Coverage Foldwidth1 oops btw btwN Debug
2523              
2524             =cut