shemp has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, i am wondering if there is any way to get Data::Dumper to maintain tie() information on something that was dumped? Here is some sample code and output, demonsrating that when eval'ing a dumped string, the tie is gone.

use strict; use warnings; use Data::Dumper; use Tie::IxHash; { tie (my %x, 'Tie::IxHash'); %x = ( 'A' => 1, 'B' => 2, 'C' => 3, ); print join "", map { "$_ = $x{$_}\n" } keys %x; print "\n"; my $dumped; { local $Data::Dumper::Terse = 1; $dumped = Dumper(\%x); } print "Dumper: $dumped\n\n"; my $y = eval $dumped; print join "", map { "$_ = $y->{$_}\n" } keys %$y; }
And here is the output:
A = 1
B = 2
C = 3

Dumper: {
          'A' => '1',
          'B' => '2',
          'C' => '3'
        }


A = 1
C = 3
B = 2
Its obvious that the problem is in the Dumper(), not the eval, because the value of $dumped does not contain any tie information, as a dumped object instance would have.

Any easy workarounds available?

Replies are listed 'Best First'.
Re: Tie and Data::Dumper
by kvale (Monsignor) on Jul 13, 2004 at 21:58 UTC
    An easy workaround is to also dump an auxillary list that stores the order of the keys. Then when reading that data back in, create a tied hash and load it with the key-value pairs in the specified order.

    If the keys are in a sorted order (as above) you could use use the "Sortkeys" filter of Data::Dumper.

    -Mark

Re: Tie and Data::Dumper
by ysth (Canon) on Jul 13, 2004 at 22:00 UTC
Re: Tie and Data::Dumper
by DaveH (Monk) on Jul 14, 2004 at 11:24 UTC

    Hi.

    The easiest solution is to remember that Tie::IxHash is just a normal class under the "tie" scenes. Yes, it defined a few "magic" methods (FETCH, STORE, etc), but it is still just a variable blessed into a class. You can use this property to create a Tie::IxHash object, freeze this object with Data::Dumper, then used the thawed Tie::IxHash object to create a new tied hash.

    Something like this:

    #!perl use strict; use warnings; use Data::Dumper qw(Dumper); use Tie::IxHash; tie (my %x, 'Tie::IxHash'); %x = ( 'A' => 1, 'B' => 2, 'C' => 3, ); print join "", (map { "$_ = $x{$_}\n" } keys %x), "\n"; my $x = Tie::IxHash->new(%x); my $dumped; { local $Data::Dumper::Terse = 1; $dumped = Dumper($x); } print "Dumper: $dumped\n"; undef $x; print "\$x is undef\n\n" unless $x; my $y = eval $dumped; tie (my %y, 'Tie::IxHash'); @y{$y->Keys} = $y->Values; print join "", (map { "$_ = $y{$_}\n" } keys %y), "\n"; __END__ A = 1 B = 2 C = 3 Dumper: bless( [ { 'A' => '0', 'C' => '2', 'B' => '1' }, [ 'A', 'B', 'C' ], [ '1', '2', '3' ], 0 ], 'Tie::IxHash' ) $x is undef A = 1 B = 2 C = 3

    I hope that this helps.

    Cheers,

    -- Dave :-)


    $q=[split+qr,,,q,~swmi,.$,],+s.$.Em~w^,,.,s,.,$&&$$q[pos],eg,print
Re: Tie and Data::Dumper
by eserte (Deacon) on Jul 14, 2004 at 14:58 UTC
    If all you want is persistance through serialization/deserialization and does not mind the non-readable format for humans, then you should try Storable instead of Data::Dumper.