From c84bb220160ad5b9d2e8319292d46d235795e4e2 Mon Sep 17 00:00:00 2001 From: Matt S Trout Date: Sat, 24 Sep 2022 16:29:52 +0000 Subject: first cut of recursive data structure handling --- Changes | 2 ++ lib/Data/Dumper/Compact.pm | 43 +++++++++++++++++++++++++++++++++++++++---- lib/JSON/Dumper/Compact.pm | 10 ++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index 69ef3ef..9d7ba8a 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,7 @@ Revision history for Data-Dumper-Compact + - Handle recursive data structures with $_ deref in perl and JSON Reference + 0.005002 - 2020-06-07 - Fix JSON::Dumper::Compact diff --git a/lib/Data/Dumper/Compact.pm b/lib/Data/Dumper/Compact.pm index 28f554a..aef3970 100644 --- a/lib/Data/Dumper/Compact.pm +++ b/lib/Data/Dumper/Compact.pm @@ -87,14 +87,28 @@ sub dump_cb { } sub expand { - my ($self, $data) = @_; + my ($self, $data, $p) = @_; + local $self->{expand_seen} = {} unless $self->{expand_seen}; + my $this_path = [ + ($self->{expand_path} ? @{$self->{expand_path}} : ()), + (defined($p) ? ($p) : ()) + ]; + if (ref($data)) { + if (my $seen_path = $self->{expand_seen}{$data}) { + return [ ref => $seen_path ]; + } else { + $self->{expand_seen}{$data} = $this_path; + } + } + local $self->{expand_path} = $this_path; if (ref($data) eq 'HASH') { return [ hash => [ [ sort keys %$data ], - { map +($_ => $self->expand($data->{$_})), keys %$data } + { map +($_ => $self->expand($data->{$_}, [ key => $_ ])), sort keys %$data } ] ]; } elsif (ref($data) eq 'ARRAY') { - return [ array => [ map $self->expand($_), @$data ] ]; + my $idx = 0; + return [ array => [ map $self->expand($_, [ idx => $idx++ ]), @$data ] ]; } elsif (blessed($data) and my $ret = $self->_expand_blessed($data)) { return $ret; } @@ -131,7 +145,7 @@ sub _transform { $payload->[0], { map +( $_ => $self->_transform($h{$_}, [ @$path, $_ ]) - ), keys %h + ), sort keys %h }, ]; } elsif ($type eq 'array') { @@ -315,6 +329,7 @@ sub _format_hash { my ($self, $payload) = @_; my ($keys, $hash) = @$payload; return '{}' unless @$keys; + @$keys = sort @$keys; my %k = (map +( $_ => $self->_format_hashkey($_)), @$keys ); @@ -389,6 +404,26 @@ sub _format_blessed { return 'bless( '.$self->_format($content).qq{, "${class}"}.' )'; } +sub _format_ref { + my ($self, $payload) = @_; + return '$_->'.join('', + map { + if ($_->[0] eq 'key') { + my $quoted = quotemeta($_->[1]); + if ($_->[1] eq $quoted) { + '{'.$quoted.'}' + } else { + '{"'.$quoted.'"}' + } + } elsif ($_->[0] eq 'idx') { + '['.$_->[1].']' + } else { + die "Invalid ref element type ".$_->[0]; + } + } @$payload + ); +} + 1; __END__ diff --git a/lib/JSON/Dumper/Compact.pm b/lib/JSON/Dumper/Compact.pm index ff82f72..16c74dc 100644 --- a/lib/JSON/Dumper/Compact.pm +++ b/lib/JSON/Dumper/Compact.pm @@ -46,6 +46,16 @@ sub _format_blessed { ] ]); } +sub _format_ref { + my ($self, $payload) = @_; + my %subst = ('/' => '~1', '~' => '~0'); + my @path = map { (my $x = $_->[1]) =~ s{[/~]}{$subst{$_}}eg; $x } @$payload; + return $self->format([ hash => [ + [ '$ref' ], + { '$ref' => [ string => join('/', '#', @path) ] }, + ] ]); +} + sub encode { shift->dump(@_) } sub decode { -- cgit v1.2.3 From 91c0f631ff29b56bbc622afdfbdecd52bcad63a2 Mon Sep 17 00:00:00 2001 From: Matt S Trout Date: Sat, 24 Sep 2022 16:30:05 +0000 Subject: Bumping version to 0.006000 --- lib/Data/Dumper/Compact.pm | 2 +- lib/Devel/DDCWarn.pm | 2 +- lib/JSON/Dumper/Compact.pm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Data/Dumper/Compact.pm b/lib/Data/Dumper/Compact.pm index aef3970..e06cd49 100644 --- a/lib/Data/Dumper/Compact.pm +++ b/lib/Data/Dumper/Compact.pm @@ -5,7 +5,7 @@ use Scalar::Util qw(blessed reftype); use Data::Dumper (); use Mu::Tiny; -our $VERSION = '0.005002'; +our $VERSION = '0.006000'; $VERSION =~ tr/_//d; sub import { diff --git a/lib/Devel/DDCWarn.pm b/lib/Devel/DDCWarn.pm index 300411d..9df5aca 100644 --- a/lib/Devel/DDCWarn.pm +++ b/lib/Devel/DDCWarn.pm @@ -4,7 +4,7 @@ use strictures 2; use Data::Dumper::Compact; use base qw(Exporter); -our $VERSION = '0.005002'; +our $VERSION = '0.006000'; $VERSION =~ tr/_//d; our @EXPORT = map +($_, $_.'T'), qw(Df Dto Dwarn Derr); diff --git a/lib/JSON/Dumper/Compact.pm b/lib/JSON/Dumper/Compact.pm index 16c74dc..2b4c5a7 100644 --- a/lib/JSON/Dumper/Compact.pm +++ b/lib/JSON/Dumper/Compact.pm @@ -4,7 +4,7 @@ use JSON::MaybeXS; use Mu::Tiny; use Class::Method::Modifiers; -our $VERSION = '0.005002'; +our $VERSION = '0.006000'; $VERSION =~ tr/_//d; extends 'Data::Dumper::Compact'; -- cgit v1.2.3 From 006b3373d6aed4f240f4ae8f7470700be0e6b4a6 Mon Sep 17 00:00:00 2001 From: Matt S Trout Date: Sat, 24 Sep 2022 16:30:50 +0000 Subject: Release commit for 0.006000 - Handle recursive data structures with $_ deref in perl and JSON Reference --- Changes | 1 + 1 file changed, 1 insertion(+) diff --git a/Changes b/Changes index 9d7ba8a..0a6e37e 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ Revision history for Data-Dumper-Compact +0.006000 - 2022-09-24 - Handle recursive data structures with $_ deref in perl and JSON Reference 0.005002 - 2020-06-07 -- cgit v1.2.3