📄 dumpvalue.pm
字号:
my ($package, $off, $key, $val, $all) = @_; local(*stab) = $val; my $fileno; if (($key !~ /^_</ or $self->{dumpDBFiles}) and defined $stab) { print( (' ' x $off) . "\$", &unctrl($key), " = " ); $self->DumpElem($stab, 3+$off); } if (($key !~ /^_</ or $self->{dumpDBFiles}) and @stab) { print( (' ' x $off) . "\@$key = (\n" ); $self->unwrap(\@stab,3+$off) ; print( (' ' x $off) . ")\n" ); } if ($key ne "main::" && $key ne "DB::" && %stab && ($self->{dumpPackages} or $key !~ /::$/) && ($key !~ /^_</ or $self->{dumpDBFiles}) && !($package eq "Dumpvalue" and $key eq "stab")) { print( (' ' x $off) . "\%$key = (\n" ); $self->unwrap(\%stab,3+$off) ; print( (' ' x $off) . ")\n" ); } if (defined ($fileno = fileno(*stab))) { print( (' ' x $off) . "FileHandle($key) => fileno($fileno)\n" ); } if ($all) { if (defined &stab) { $self->dumpsub($off, $key); } }}sub CvGV_name { my $self = shift; my $in = shift; return if $self->{skipCvGV}; # Backdoor to avoid problems if XS broken... $in = \&$in; # Hard reference... eval {require Devel::Peek; 1} or return; my $gv = Devel::Peek::CvGV($in) or return; *$gv{PACKAGE} . '::' . *$gv{NAME};}sub dumpsub { my $self = shift; my ($off,$sub) = @_; my $ini = $sub; my $s; $sub = $1 if $sub =~ /^\{\*(.*)\}$/; my $subref = defined $1 ? \&$sub : \&$ini; my $place = $DB::sub{$sub} || (($s = $subs{"$subref"}) && $DB::sub{$s}) || (($s = $self->CvGV_name($subref)) && $DB::sub{$s}) || ($self->{subdump} && ($s = $self->findsubs("$subref")) && $DB::sub{$s}); $s = $sub unless defined $s; $place = '???' unless defined $place; print( (' ' x $off) . "&$s in $place\n" );}sub findsubs { my $self = shift; return undef unless %DB::sub; my ($addr, $name, $loc); while (($name, $loc) = each %DB::sub) { $addr = \&$name; $subs{"$addr"} = $name; } $self->{subdump} = 0; $subs{ shift() };}sub dumpvars { my $self = shift; my ($package,@vars) = @_; local(%address,$^W); my ($key,$val); $package .= "::" unless $package =~ /::$/; *stab = *main::; while ($package =~ /(\w+?::)/g) { *stab = $ {stab}{$1}; } $self->{TotalStrings} = 0; $self->{Strings} = 0; $self->{CompleteTotal} = 0; while (($key,$val) = each(%stab)) { return if $DB::signal and $self->{stopDbSignal}; next if @vars && !grep( matchvar($key, $_), @vars ); if ($self->{usageOnly}) { $self->globUsage(\$val, $key) if ($package ne 'Dumpvalue' or $key ne 'stab') and ref(\$val) eq 'GLOB'; } else { $self->dumpglob($package, 0,$key, $val); } } if ($self->{usageOnly}) { print <<EOP;String space: $self->{TotalStrings} bytes in $self->{Strings} strings.EOP $self->{CompleteTotal} += $self->{TotalStrings}; print <<EOP;Grand total = $self->{CompleteTotal} bytes (1 level deep) + overhead.EOP }}sub scalarUsage { my $self = shift; my $size; if (UNIVERSAL::isa($_[0], 'ARRAY')) { $size = $self->arrayUsage($_[0]); } elsif (UNIVERSAL::isa($_[0], 'HASH')) { $size = $self->hashUsage($_[0]); } elsif (!ref($_[0])) { $size = length($_[0]); } $self->{TotalStrings} += $size; $self->{Strings}++; $size;}sub arrayUsage { # array ref, name my $self = shift; my $size = 0; map {$size += $self->scalarUsage($_)} @{$_[0]}; my $len = @{$_[0]}; print "\@$_[1] = $len item", ($len > 1 ? "s" : ""), " (data: $size bytes)\n" if defined $_[1]; $self->{CompleteTotal} += $size; $size;}sub hashUsage { # hash ref, name my $self = shift; my @keys = keys %{$_[0]}; my @values = values %{$_[0]}; my $keys = $self->arrayUsage(\@keys); my $values = $self->arrayUsage(\@values); my $len = @keys; my $total = $keys + $values; print "\%$_[1] = $len item", ($len > 1 ? "s" : ""), " (keys: $keys; values: $values; total: $total bytes)\n" if defined $_[1]; $total;}sub globUsage { # glob ref, name my $self = shift; local *stab = *{$_[0]}; my $total = 0; $total += $self->scalarUsage($stab) if defined $stab; $total += $self->arrayUsage(\@stab, $_[1]) if @stab; $total += $self->hashUsage(\%stab, $_[1]) if %stab and $_[1] ne "main::" and $_[1] ne "DB::"; #and !($package eq "Dumpvalue" and $key eq "stab")); $total;}1;=head1 NAMEDumpvalue - provides screen dump of Perl data.=head1 SYNOPSIS use Dumpvalue; my $dumper = new Dumpvalue; $dumper->set(globPrint => 1); $dumper->dumpValue(\*::); $dumper->dumpvars('main'); my $dump = $dumper->stringify($some_value);=head1 DESCRIPTION=head2 CreationA new dumper is created by a call $d = new Dumpvalue(option1 => value1, option2 => value2)Recognized options:=over 4=item C<arrayDepth>, C<hashDepth>Print only first N elements of arrays and hashes. If false, prints all theelements.=item C<compactDump>, C<veryCompact>Change style of array and hash dump. If true, short arraymay be printed on one line.=item C<globPrint>Whether to print contents of globs.=item C<dumpDBFiles>Dump arrays holding contents of debugged files.=item C<dumpPackages>Dump symbol tables of packages.=item C<dumpReused>Dump contents of "reused" addresses.=item C<tick>, C<quoteHighBit>, C<printUndef>Change style of string dump. Default value of C<tick> is C<auto>, onecan enable either double-quotish dump, or single-quotish by setting itto C<"> or C<'>. By default, characters with high bit set are printedI<as is>. If C<quoteHighBit> is set, they will be quoted.=item C<usageOnly>rudimentally per-package memory usage dump. If set,C<dumpvars> calculates total size of strings in variables in the package.=item unctrlChanges the style of printout of strings. Possible values areC<unctrl> and C<quote>.=item subdumpWhether to try to find the subroutine name given the reference.=item bareStringifyWhether to write the non-overloaded form of the stringify-overloaded objects.=item quoteHighBitWhether to print chars with high bit set in binary or "as is".=item stopDbSignalWhether to abort printing if debugger signal flag is raised.=backLater in the life of the object the methods may be queries with get()method and set() method (which accept multiple arguments).=head2 Methods=over 4=item dumpValue $dumper->dumpValue($value); $dumper->dumpValue([$value1, $value2]);Prints a dump to the currently selected filehandle.=item dumpValues $dumper->dumpValues($value1, $value2);Same as C< $dumper->dumpValue([$value1, $value2]); >.=item stringify my $dump = $dumper->stringify($value [,$noticks] );Returns the dump of a single scalar without printing. If the secondargument is true, the return value does not contain enclosing ticks.Does not handle data structures.=item dumpvars $dumper->dumpvars('my_package'); $dumper->dumpvars('my_package', 'foo', '~bar$', '!......');The optional arguments are considered as literal strings unless theystart with C<~> or C<!>, in which case they are interpreted as regularexpressions (possibly negated).The second example prints entries with names C<foo>, and also entrieswith names which ends on C<bar>, or are shorter than 5 chars.=item set_quote $d->set_quote('"');Sets C<tick> and C<unctrl> options to suitable values for printout with thegiven quote char. Possible values are C<auto>, C<'> and C<">.=item set_unctrl $d->set_unctrl('unctrl');Sets C<unctrl> option with checking for an invalid argument.Possible values are C<unctrl> and C<quote>.=item compactDump $d->compactDump(1);Sets C<compactDump> option. If the value is 1, sets to a reasonablebig number.=item veryCompact $d->veryCompact(1);Sets C<compactDump> and C<veryCompact> options simultaneously.=item set $d->set(option1 => value1, option2 => value2);=item get @values = $d->get('option1', 'option2');=back=cut
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -