eval of Data::Dumper output not same as original data structure

Discussion in 'Perl Misc' started by himanshu.garg@gmail.com, Aug 1, 2007.

  1. Guest

    Why aren't the outputs of the two print statements same. I want
    to reconstruct %hash1 into %hash2.

    ========================================
    use strict;
    use Data::Dumper;

    my %hash1 = (key1 => 'value1', 'key2' => 'value2');

    my %hash2 = eval Dumper(%hash1);

    print Dumper(%hash1);

    print Dumper(%hash2);
    ========================================

    I am trying to save the Dumper output to the database and later trying
    to get the same data structure.

    Thank You,
    HG
    , Aug 1, 2007
    #1
    1. Advertising

  2. On Aug 1, 8:05 am, wrote:
    > Why aren't the outputs of the two print statements same. I want
    > to reconstruct %hash1 into %hash2.
    >
    > ========================================
    > use strict;
    > use Data::Dumper;
    >
    > my %hash1 = (key1 => 'value1', 'key2' => 'value2');
    >
    > my %hash2 = eval Dumper(%hash1);
    >
    > print Dumper(%hash1);
    >
    > print Dumper(%hash2);
    > ========================================
    >
    > I am trying to save the Dumper output to the database and later trying
    > to get the same data structure.


    You need to think of Dumper() as taking a single scalar argument


    my $hash1 = { key1 => 'value1', 'key2' => 'value2' };

    my $hash2 = do { no strict 'vars'; eval Dumper($hash1) };

    Note, this has the side effect of creating a package variable $VAR1.

    To serialise Perl hashes or arrays into human-readable database large
    (text) objects I use.

    sub linear_dump {
    unless ($dumper) {
    $dumper = Data::Dumper->new([]);
    $dumper->Indent(0);
    }
    $dumper->Reset->Values([shift]);
    my $dumped = $dumper->Dump;
    $dumped =~ s/\A\$VAR1 = [\[{](.*)[\]}];\Z/$1/s or die;
    $dumped;
    }

    sub linear_undump {
    no warnings 'uninitialized';
    my @data = eval join ' , ' => 'undef' , @_;
    die "Error in cached info @_: $@" if $@;
    shift @data;
    return +{ @data } unless wantarray;
    @data;
    }

    If readability is not an issue consider also using BLOBs and Storable.

    Usual caveats about eval(STRING) apply: anyone who can write to the
    database can place arbitrary executable code in it. Use this technique
    only if you are satisfied that write access to the database is
    restricted to people who could edit your scripts anyhow.
    Brian McCauley, Aug 1, 2007
    #2
    1. Advertising

  3. Mark Clements, Aug 1, 2007
    #3
  4. Guest

    On Aug 1, 1:44 pm, Brian McCauley <> wrote:
    > On Aug 1, 8:05 am, wrote:
    >
    >
    >
    > > Why aren't the outputs of the two print statements same. I want
    > > to reconstruct %hash1 into %hash2.

    >
    > > ========================================
    > > use strict;
    > > use Data::Dumper;

    >
    > > my %hash1 = (key1 => 'value1', 'key2' => 'value2');

    >
    > > my %hash2 = eval Dumper(%hash1);

    >
    > > print Dumper(%hash1);

    >
    > > print Dumper(%hash2);
    > > ========================================

    >
    > > I am trying to save the Dumper output to the database and later trying
    > > to get the same data structure.

    >
    > You need to think of Dumper() as taking a single scalar argument
    >
    > my $hash1 = { key1 => 'value1', 'key2' => 'value2' };
    >
    > my $hash2 = do { no strict 'vars'; eval Dumper($hash1) };
    >
    > Note, this has the side effect of creating a package variable $VAR1.
    >
    > To serialise Perl hashes or arrays into human-readable database large
    > (text) objects I use.
    >
    > [code snipped]
    >
    > If readability is not an issue consider also using BLOBs and Storable.
    >
    > Usual caveats about eval(STRING) apply: anyone who can write to the
    > database can place arbitrary executable code in it. Use this technique
    > only if you are satisfied that write access to the database is
    > restricted to people who could edit your scripts anyhow.


    Thanks for the reply. I will avoid Dumper if that is what is needed
    and use XML::Simple instead since readability is not a concern.

    Thank You,
    HG
    , Aug 1, 2007
    #4
  5. Paul Lalli Guest

    On Aug 1, 3:05 am, wrote:
    > Why aren't the outputs of the two print statements same. I want
    > to reconstruct %hash1 into %hash2.
    >
    > ========================================
    > use strict;
    > use Data::Dumper;
    >
    > my %hash1 = (key1 => 'value1', 'key2' => 'value2');
    >
    > my %hash2 = eval Dumper(%hash1);
    >
    > print Dumper(%hash1);
    >
    > print Dumper(%hash2);
    > ========================================
    >
    > I am trying to save the Dumper output to the database and later trying
    > to get the same data structure.


    You're making several mistakes with the usage of Data::Dumper.

    1) Dumper() takes a list of structures to dump. You are passing it a
    list of values (using a hash in a list context). If you want to dump
    just the single variable %hash1, you have to pass a reference to that
    hash:
    print Dumper(\%hash1);
    2) Dumper() returns a string that starts with "$VAR1 = ". If you are
    trying to eval() that string, you are trying to execute code
    containing the variable $VAR1. When you use strict, you need to pre-
    declare all your variables. You are eval'ing code without checking
    for an error. If you had checked the value of $@, you'd see that the
    eval failed because $VAR1 was not previously declared.
    3) Because the string that Dumper() returns represents code that
    assigns to a reference, if you eval that code, you are getting a
    reference out of it. You need to dereference that reference.

    There are several solutions to your problem:
    (1) Predeclare $VAR1
    $ perl -le'
    use strict;
    use Data::Dumper;
    my %hash1 = (key1 => "value1", key2 => "value2");
    my $VAR1;
    my %hash2 = %{ eval Dumper(\%hash1) };
    print Dumper(\%hash1);
    print Dumper(\%hash2);
    '
    $VAR1 = {
    'key2' => 'value2',
    'key1' => 'value1'
    };

    $VAR1 = {
    'key2' => 'value2',
    'key1' => 'value1'
    };


    (2) Use the Dump() method rather than the Dumper() function, which
    lets you set the name you wish to use for the dumped variables:
    $ perl -le'
    use strict;
    use Data::Dumper;
    my %hash1 = (key1 => "value1", key2 => "value2");
    my $hash2;
    eval Data::Dumper->Dump([\%hash1], ["hash2"]);
    print Dumper(\%hash1);
    print Dumper($hash2);
    '
    $VAR1 = {
    'key2' => 'value2',
    'key1' => 'value1'
    };

    $VAR1 = {
    'key2' => 'value2',
    'key1' => 'value1'
    };

    (3) use the Storable module instead, which has (imho) a nicer
    interface for this sort of thing, and is also a core module.
    $ perl -le'
    use strict;
    use Storable qw/freeze thaw/;
    my %hash1 = (key1 => "value1", key2 => "value2");
    my %hash2 = %{ thaw(freeze(\%hash1)) };
    use Data::Dumper;
    print Dumper(\%hash1, \%hash2);
    '
    $VAR1 = {
    'key2' => 'value2',
    'key1' => 'value1'
    };
    $VAR2 = {
    'key2' => 'value2',
    'key1' => 'value1'
    };


    Hope that helps,
    Paul Lalli
    Paul Lalli, Aug 1, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kamal
    Replies:
    0
    Views:
    979
    kamal
    Aug 12, 2003
  2. A
    Replies:
    27
    Views:
    1,580
    Jorgen Grahn
    Apr 17, 2011
  3. Replies:
    1
    Views:
    109
    Uri Guttman
    Jan 30, 2007
  4. John
    Replies:
    0
    Views:
    87
  5. Marc Girod

    to eval or not to eval?

    Marc Girod, Apr 19, 2011, in forum: Perl Misc
    Replies:
    2
    Views:
    149
    Marc Girod
    Apr 19, 2011
Loading...

Share This Page