Dumper

Discussion in 'Perl Misc' started by George Mpouras, Oct 15, 2013.

  1. # this works



    use Data::Dumper; $Data::Dumper::purity=1;
    my $dmp;
    my %hash1 = ('k1'=>'v1','k2'=>'v2');
    $dmp = Data::Dumper::Dumper( \%hash1 );;
    my $hash2 = eval $dmp; print Data::Dumper::Dumper($hash2);


    # this is not

    use strict; use warnings;
    use Data::Dumper; $Data::Dumper::purity=1;
    my $dmp;
    my %hash1 = ('k1'=>'v1','k2'=>'v2');
    $dmp = Data::Dumper::Dumper( \%hash1 );;
    my $hash2 = eval $dmp; print Data::Dumper::Dumper($hash2);


    what I am doing wrong
     
    George Mpouras, Oct 15, 2013
    #1
    1. Advertising


  2. > # this works
    >
    >
    >
    > use Data::Dumper; $Data::Dumper::purity=1;
    > my $dmp;
    > my %hash1 = ('k1'=>'v1','k2'=>'v2');
    > $dmp = Data::Dumper::Dumper( \%hash1 );;
    > my $hash2 = eval $dmp; print Data::Dumper::Dumper($hash2);
    >
    >
    > # this is not
    >
    > use strict; use warnings;
    > use Data::Dumper; $Data::Dumper::purity=1;
    > my $dmp;
    > my %hash1 = ('k1'=>'v1','k2'=>'v2');
    > $dmp = Data::Dumper::Dumper( \%hash1 );;
    > my $hash2 = eval $dmp; print Data::Dumper::Dumper($hash2);
    >
    >
    > what I am doing wrong



    after scratching my head I conclude to this

    my $hash2 = eval "our $dmp \$VAR1";
    print Data::Dumper::Dumper($hash2);

    do you think its ok;
     
    George Mpouras, Oct 15, 2013
    #2
    1. Advertising

  3. George Mpouras <>
    writes:

    [...]

    > # this is not
    >
    > use strict; use warnings;
    > use Data::Dumper; $Data::Dumper::purity=1;
    > my $dmp;
    > my %hash1 = ('k1'=>'v1','k2'=>'v2');
    > $dmp = Data::Dumper::Dumper( \%hash1 );;
    > my $hash2 = eval $dmp; print Data::Dumper::Dumper($hash2);
    >
    >
    > what I am doing wrong


    One could argue that the code should check whether the eval succeeded,

    use strict;
    use warnings;
    use Data::Dumper;
    $Data::Dumper::purity=1;
    my $dmp;
    my %hash1 = ('k1'=>'v1','k2'=>'v2');
    $dmp = Data::Dumper::Dumper( \%hash1 );;
    my $hash2 = eval $dmp;
    die($@) if $@;
    print Data::Dumper::Dumper($hash2);

    [NB: Don't put more than one statement on a line. That's going to make
    debugging rather painful in exchange for nothing tangible]

    But very likely, you should rather be using

    use strict;
    use warnings;
    use Data::Dumper;
    $Data::Dumper::purity=1;
    $Data::Dumper::Terse=1;
    my $dmp;
    my %hash1 = ('k1'=>'v1','k2'=>'v2');
    $dmp = Data::Dumper::Dumper( \%hash1 );;
    print STDERR ($dmp);
    my $hash2 = eval $dmp;
    die($@) if $@;
    print Data::Dumper::Dumper($hash2);

    so that $dmp contains the Perl code necessary to create an anonymous
    hash with the intended content instead of the $VAR1 = { ... } strict
    disallows.
     
    Rainer Weikusat, Oct 15, 2013
    #3
  4. > $Data::Dumper::Terse=1;

    perfect
     
    George Mpouras, Oct 15, 2013
    #4
  5. George Mpouras

    Guest

    On Tuesday, October 15, 2013 6:36:07 AM UTC-6, George Mpouras wrote:
    > # this works
    >
    >
    >
    >
    >
    >
    >
    > use Data::Dumper; $Data::Dumper::purity=1;
    >
    > my $dmp;
    >
    > my %hash1 = ('k1'=>'v1','k2'=>'v2');
    >
    > $dmp = Data::Dumper::Dumper( \%hash1 );;
    >
    > my $hash2 = eval $dmp; print Data::Dumper::Dumper($hash2);
    >
    >
    >
    >
    >
    > # this is not
    >
    >
    >
    > use strict; use warnings;
    >
    > use Data::Dumper; $Data::Dumper::purity=1;
    >
    > my $dmp;
    >
    > my %hash1 = ('k1'=>'v1','k2'=>'v2');
    >
    > $dmp = Data::Dumper::Dumper( \%hash1 );;
    >
    > my $hash2 = eval $dmp; print Data::Dumper::Dumper($hash2);
    >
    >
    >
    >
    >
    > what I am doing wrong



    Dear George,

    By now you've figured out that the $VAR1 variable in the Data::Dumper::Dumper() output is conflicting with "use strict;", and that setting $Data::Dumper::Terse to 1 removes that conflict.

    However, I question why you're dumping the output to Dumper into a string and then eval()ing it to assign to another hash. Is it because you want a convenient way to create a deep copy of a hash/array/object?

    If so, I recommend using the Storable module instead. It's a standard module in Perl these days. It avoids the use of having to use eval(), and it's probably considerably quicker than doing the same thing with Data::Dumper.

    Here I'm giving you three different ways to use the Storable module, oneof which should nicely match what you're trying to do:


    {
    # Making a copy from a temporary string (using freeze() and thaw()):
    use strict;
    use warnings;
    my %hash1 = ('k1' => 'v1', 'k2' => 'v2');
    use Storable;
    my $tempString = Storable::freeze( \%hash1 );
    my %hash2 = %{ Storable::thaw($tempString) };
    use Data::Dumper; print Data::Dumper::Dumper( \%hash2 );
    }


    {
    # Making a copy from a file (using nstore() and retrieve()):
    use strict;
    use warnings;
    my %hash1 = ('k1' => 'v1', 'k2' => 'v2');
    my $fileName = "file.tmp";
    use Storable;
    Storable::nstore( \%hash1, $fileName );
    my %hash2 = %{ Storable::retrieve($fileName) };
    use Data::Dumper; print Data::Dumper::Dumper( \%hash2 );
    }


    {
    # Making a deep copy directly (using dclone()):
    use strict;
    use warnings;
    my %hash1 = ('k1' => 'v1', 'k2' => 'v2');
    use Storable;
    my %hash2 = %{ Storable::dclone( \%hash1 ) };
    use Data::Dumper; print Data::Dumper::Dumper( \%hash2 );
    }


    If all you want to do is to perform a deep copy on a hash/array/object, I advise using the third approach I listed (the one that uses Storable::dclone()). But if you want the data to a file to retrieve later, I recommend the approach that uses nstore() and retrieve().

    Using eval() to copy data is not always a great idea. For one thing, ifyou the data that you eval() comes from a file, someone could have easily tampered with the contents of the file, placing malicious Perl code in the file that ends up getting executed when you eval() it.

    So if all you want is to store data to a file (for later retrieval), useStorable::nstore() (and retrieve it later with Storable::retrieve()) instead of Data::Dumper. Or if all you want is to create a deep copy/clone of an object, use Storable::dclone().

    The main reason you'd want to use Data::Dumper is to visually inspect the data you're working with, which is something you can't do easily with theStorable module (which is why I'm using Data::Dumper in all three of my examples above). (But if you only really needed to visually inspect the data, there'd be no reason to eval() it later.)

    So my advice is to use the Storable module instead of Data::Dumper, unless you need to manually inspect the contents of a scalar/array/hash/object.

    I hope this is helpful, George.

    -- Jean-Luc
     
    , Nov 6, 2013
    #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:
    1,006
    kamal
    Aug 12, 2003
  2. Eric
    Replies:
    0
    Views:
    4,526
  3. rc
    Replies:
    3
    Views:
    1,906
    Chris Uppal
    Aug 16, 2004
  4. Sam

    Data::Dumper for Java?

    Sam, Nov 30, 2004, in forum: Java
    Replies:
    4
    Views:
    7,912
    Anonymous
    Feb 11, 2011
  5. Edward wijaya

    Data::Dumper for Python

    Edward wijaya, Oct 28, 2004, in forum: Python
    Replies:
    7
    Views:
    1,071
    A.M. Kuchling
    Oct 29, 2004
Loading...

Share This Page