http://qs1969.pair.com?node_id=1149872


in reply to Re^2: Storing state of execution
in thread Storing state of execution

Data::Dumper does not dump everything, sometimes, it just generates dummy code
Unless you specify
$Data::Dumper::Deparse = 1;
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

Replies are listed 'Best First'.
Re^4: Storing state of execution
by afoken (Chancellor) on Dec 11, 2015 at 20:16 UTC

    But the deparsed code does not contain all required information in all cases:

    #!/usr/bin/perl -w use strict; use warnings; use feature 'state'; use Data::Dumper; $Data::Dumper::Deparse=1; our %data; our $VAR1; sub insert { my ($name,$href)=@_; $href->{$name}=$href->{'nextID'}->(); print $name," => ",$href->{$name},"\n"; } sub init_data { %data=( nextID => sub { state $n=100; $n++; print "\$n is now $n\n"; return $n; } ); } init_data(); print "Working with the original:\n\n"; insert(a => \%data); insert(b => \%data); insert(c => \%data); my $dump=Dumper(\%data); print "\nData::Dumper output:\n\n"; print "$dump\n"; print "\nWorking with the original again:\n\n"; insert(d => \%data); print "\nWorking with the re-evaluated Data::Dumper output:\n\n"; eval $dump; die $@ if $@; insert(d => $VAR1);

    Output:

    Working with the original: $n is now 101 a => 101 $n is now 102 b => 102 $n is now 103 c => 103 Data::Dumper output: $VAR1 = { 'c' => 103, 'a' => 101, 'nextID' => sub { use warnings; use strict; use feature 'state'; state $n = 100; ++$n; print "\$n is now $n\n"; return $n; }, 'b' => 102 }; Working with the original again: $n is now 104 d => 104 Working with the re-evaluated Data::Dumper output: $n is now 101 d => 101

    Yes, this is constructed. But it shows that deparsing the sub reference is not sufficient to restore all state after a Data::Dumper-eval cycle. The state of $n is lost, creating two colliding IDs.

    It gets even worse without the state feature:

    #!/usr/bin/perl -w use strict; use warnings; use Data::Dumper; $Data::Dumper::Deparse=1; our %data; our $VAR1; sub insert { my ($name,$href)=@_; $href->{$name}=$href->{'nextID'}->(); print $name," => ",$href->{$name},"\n"; } sub init_data { my $n=100; %data=( nextID => sub { $n++; print "\$n is now $n\n"; return $n; } ); } init_data(); print "Working with the original:\n\n"; insert(a => \%data); insert(b => \%data); insert(c => \%data); my $dump=Dumper(\%data); print "\nData::Dumper output:\n\n"; print "$dump\n"; print "\nWorking with the original again:\n\n"; insert(d => \%data); print "\nWorking with the re-evaluated Data::Dumper output:\n\n"; eval $dump; die $@ if $@; insert(d => $VAR1);

    Output:

    Working with the original: $n is now 101 a => 101 $n is now 102 b => 102 $n is now 103 c => 103 Data::Dumper output: $VAR1 = { 'c' => 103, 'b' => 102, 'a' => 101, 'nextID' => sub { use warnings; use strict; ++$n; print "\$n is now $n\n"; return $n; } }; Working with the original again: $n is now 104 d => 104 Working with the re-evaluated Data::Dumper output: Global symbol "$n" requires explicit package name at (eval 8) line 8. Global symbol "$n" requires explicit package name at (eval 8) line 9. Global symbol "$n" requires explicit package name at (eval 8) line 10.

    On the other hand, complaining loudly is better than just generating repeated IDs.

    Stupidly removing use strict and use warnings from the code hides the error, and results in worse behaviour:

    #!/usr/bin/perl -w use Data::Dumper; $Data::Dumper::Deparse=1; our %data; our $VAR1; sub insert { my ($name,$href)=@_; $href->{$name}=$href->{'nextID'}->(); print $name," => ",$href->{$name},"\n"; } sub init_data { my $n=100; %data=( nextID => sub { $n++; print "\$n is now $n\n"; return $n; } ); } init_data(); print "Working with the original:\n\n"; insert(a => \%data); insert(b => \%data); insert(c => \%data); my $dump=Dumper(\%data); print "\nData::Dumper output:\n\n"; print "$dump\n"; print "\nWorking with the original again:\n\n"; insert(d => \%data); print "\nWorking with the re-evaluated Data::Dumper output:\n\n"; eval $dump; die $@ if $@; insert(d => $VAR1);

    Output:

    Working with the original: $n is now 101 a => 101 $n is now 102 b => 102 $n is now 103 c => 103 Data::Dumper output: $VAR1 = { 'a' => 101, 'c' => 103, 'nextID' => sub { ++$n; print "\$n is now $n\n"; return $n; }, 'b' => 102 }; Working with the original again: $n is now 104 d => 104 Working with the re-evaluated Data::Dumper output: $n is now 1 d => 1

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)