Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > eval of Data::Dumper output not same as original data structure

Reply
Thread Tools

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

 
 
himanshu.garg@gmail.com
Guest
Posts: n/a
 
      08-01-2007
Why aren't the outputs of the two print statements same. I want
to reconstruct %hash1 into %hash2.

========================================
use strict;
use Data:umper;

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

 
Reply With Quote
 
 
 
 
Brian McCauley
Guest
Posts: n/a
 
      08-01-2007
On Aug 1, 8:05 am, (E-Mail Removed) wrote:
> Why aren't the outputs of the two print statements same. I want
> to reconstruct %hash1 into %hash2.
>
> ========================================
> use strict;
> use Data:umper;
>
> 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:umper->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.


 
Reply With Quote
 
 
 
 
Mark Clements
Guest
Posts: n/a
 
      08-01-2007
Brian McCauley wrote:

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

<snip Data:umper solution>
>
> If readability is not an issue consider also using BLOBs and Storable.

For human-readable I'd also suggest one of the YAML implementations.

eg

http://search.cpan.org/~ingy/YAML-0.65/lib/YAML.pm
http://search.cpan.org/~audreyt/YAML.../YAML/Syck.pod

Mark
 
Reply With Quote
 
himanshu.garg@gmail.com
Guest
Posts: n/a
 
      08-01-2007
On Aug 1, 1:44 pm, Brian McCauley <(E-Mail Removed)> wrote:
> On Aug 1, 8:05 am, (E-Mail Removed) wrote:
>
>
>
> > Why aren't the outputs of the two print statements same. I want
> > to reconstruct %hash1 into %hash2.

>
> > ========================================
> > use strict;
> > use Data:umper;

>
> > 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

 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      08-01-2007
On Aug 1, 3:05 am, (E-Mail Removed) wrote:
> Why aren't the outputs of the two print statements same. I want
> to reconstruct %hash1 into %hash2.
>
> ========================================
> use strict;
> use Data:umper;
>
> 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:umper.

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:umper;
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:umper;
my %hash1 = (key1 => "value1", key2 => "value2");
my $hash2;
eval Data:umper->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:umper;
print Dumper(\%hash1, \%hash2);
'
$VAR1 = {
'key2' => 'value2',
'key1' => 'value1'
};
$VAR2 = {
'key2' => 'value2',
'key1' => 'value1'
};


Hope that helps,
Paul Lalli

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
to eval or not to eval? Marc Girod Perl Misc 2 04-19-2011 01:13 PM
Simple structure and copying data to pointer of the same structure A C++ 27 04-16-2011 11:07 PM
DataBinder.Eval and Eval. craigkenisston@hotmail.com ASP .Net 1 06-16-2006 05:33 PM
DataBinder.Eval for an object's property property... like Eval(Container.DataItem,"Version.Major") Eric Newton ASP .Net 3 04-04-2005 10:11 PM
Perl complex data structure ... how to get more flexible access? how to avoid eval? valued customer Perl Misc 10 02-25-2004 06:42 AM



Advertisments