File Coverage

blib/lib/Data/Dumper/Interp.pm
Criterion Covered Total %
statement 541 679 79.6
branch 217 408 53.1
condition 71 109 65.1
subroutine 91 115 79.1
pod 18 30 60.0
total 938 1341 69.9


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