Let's say I have a text file created using Data::Dumper
, along the lines of:
my $x = [ { foo => 'bar', asdf => undef }, 0, -4, [ [] ] ];
I'd like to read that file back in and get $x
back. I tried this:
my $vars;
{
undef $/;
$vars = <FILE>;
}
eval $vars;
But it didn't seem to work -- $x
not only isn't defined, when I try to use it I get a warning that
Global symbol $x requires explicit package name.
What's the right way to do this? (And yes, I know it's ugly. It's a quick utility script, not e.g., a life-support system.)
As others have already said, you'd probably be better off storing the data in a better serialisation format:
Personally, I think I'd aim for YAML or JSON... you can't get much easier than:
my $data = YAML::Any::LoadFile($filename);
Here's a thread that provides a couple different options: Undumper
If you're just looking for data persistence the Storable module might be your best bet.
By default, Data::Dumper output cannot be parsed by eval, especially if the data structure being dumped is circular in some way. However, you can set
$Data::Dumper::Purity = 1;
or
$obj->Purity(1);
where obj
is a Data::Dumper object. Either of these will cause Data::Dumper to produce output that can be parsed by eval.
See the Data::Dumper documenatation at CPAN for all the details.
As Rich says, you probably don't want to use Data::Dumper for persistence, but rather something like Storable.
However, to answer the question asked... IIRC, Data::Dumper doesn't declare your variables to be my
, so are you doing that yourself somehow?
To be able to eval
the data back in, the variable needs to not be my
within the eval. If your text file contained this:
$x = [ { foo => 'bar', asdf => undef }, 0, -4, [ [] ] ];
Then this would work:
my $vars;
{
undef $/;
$vars = <FILE>;
}
my $x;
eval $vars;
print $x;
If you want to stay with something easy and human-readable, simply use the Data::Dump
module instead of Data::Dumper
. Basically, it is Data::Dumper
done right -- it produces valid Perl expressions ready for assignment, without creating all those weird $VAR1
, $VAR2
etc. variables.
Then, if your code looks like:
my $x = [ { foo => 'bar', asdf => undef }, 0, -4, [ [] ] ];
Save it using:
use Data::Dump "pp";
open F, ">dump.txt";
print F pp($x);
This produces a file dump.txt
that looks like (on my PC at least):
[{ asdf => undef, foo => "bar" }, 0, -4, [[]]]
Load it using:
open F, "dump.txt";
my $vars;
{ local $/ = undef; $vars = <F>; }
my $x = eval $vars;
Note that
$/
in its own block, you should use local
to ensure it's value is actually restored at the end of the block; andeval()
needs to be assigned to $x
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With