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". ;-)

In reply to Re^4: Storing state of execution by afoken
in thread Storing state of execution by bagyi

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.