Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re^4: Storing state of execution

by afoken (Chancellor)
on Dec 11, 2015 at 20:16 UTC ( [id://1150069]=note: print w/replies, xml ) Need Help??


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

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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1150069]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (7)
As of 2024-03-28 21:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found