X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/kivitendo-erp.git/blobdiff_plain/7f5edaa695f8e23af197c4b82b66ca2e1bbfc35e..975304c772762b6a029c21aab00f3f449ed5cdf5:/SL/LXDebug.pm diff --git a/SL/LXDebug.pm b/SL/LXDebug.pm index cedd5baec..707b89230 100644 --- a/SL/LXDebug.pm +++ b/SL/LXDebug.pm @@ -20,7 +20,7 @@ use constant STDERR_TARGET => 1; use Data::Dumper; use POSIX qw(strftime getpid); -use Scalar::Util qw(blessed reftype); +use Scalar::Util qw(blessed refaddr weaken); use Time::HiRes qw(gettimeofday tv_interval); use YAML; use SL::Request (); @@ -157,20 +157,49 @@ sub warn { $self->message(WARN, $message); } -sub _clone_for_dump { - my ($src) = @_; +sub clone_for_dump { + my ($src, $dumped) = @_; - return undef unless defined($src); - return $src->as_debug_info if blessed($src) && $src->can('as_debug_info'); - return [ map { _clone_for_dump($_) } @{ $src } ] if reftype($src) eq 'ARRAY'; - return { map { ($_ => _clone_for_dump($src->{$_})) } keys %{ $src } } if reftype($src) eq 'HASH'; - return "$src"; + return undef if !defined($src); + + $dumped ||= {}; + my $addr = refaddr($src); + + return $dumped->{$addr} if $dumped->{$addr // ''}; + + + if (blessed($src) && $src->can('as_debug_info')) { + $dumped->{$addr} = $src->as_debug_info; + + } elsif (ref($src) eq 'ARRAY') { + $dumped->{$addr} = []; + + foreach my $entry (@{ $src }) { + my $exists = !!$dumped->{refaddr($entry) // ''}; + push @{ $dumped->{$addr} }, clone_for_dump($entry, $dumped); + + weaken($dumped->{$addr}->[-1]) if $exists; + + } + + } elsif (ref($src) =~ m{^(?:HASH|Form|SL::.+)$}) { + $dumped->{$addr} = {}; + + foreach my $key (keys %{ $src }) { + my $exists = !!$dumped->{refaddr($src->{$key}) // ''}; + $dumped->{$addr}->{$key} = clone_for_dump($src->{$key}, $dumped); + + weaken($dumped->{$addr}->{$key}) if $exists; + } + } + + return $dumped->{$addr} // "$src"; } sub dump { my ($self, $level, $name, $variable, %options) = @_; - $variable = _clone_for_dump($variable); + $variable = clone_for_dump($variable); my $dumper = Data::Dumper->new([$variable]); $dumper->Sortkeys(1); $dumper->Indent(2);