How do I read back in the output of Data::Dumper?

2019-03-20 21:00发布

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

9条回答
对你真心纯属浪费
2楼-- · 2019-03-20 21:12

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.

查看更多
贼婆χ
3楼-- · 2019-03-20 21:13

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.

查看更多
对你真心纯属浪费
4楼-- · 2019-03-20 21:20

This snippet is short and worked for me (I was reading in an array). It takes the filename from the first script argument.


# Load in the Dumper'ed library data structure and eval it
my $dsname = $ARGV[0];
my @lib = do "$dsname";
查看更多
Juvenile、少年°
5楼-- · 2019-03-20 21:22

As others have already said, you'd probably be better off storing the data in a better serialisation format:

  • Storable - this is quick and easy, but fairly Perl-specific (but will satisfy your need for a quick solution in a relatively unimportant script easily)
  • YAML, using the YAML module, or YAML::Tiny, or YAML::Any as a wrapper to take advantage of whatever JSON module(s) are available on your system
  • JSON, using the JSON module, or JSON::XS for more speed (or JSON::Any as a wrapper to take advantage of whatever JSON module(s) are available on your system)
  • XML, using the XML-Simple module, or one of the other XML modules.

Personally, I think I'd aim for YAML or JSON... you can't get much easier than:

my $data = YAML::Any::LoadFile($filename);

查看更多
Summer. ? 凉城
6楼-- · 2019-03-20 21:23

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

  1. If you're bothering to put the assignment to $/ in its own block, you should use local to ensure it's value is actually restored at the end of the block; and
  2. The result of eval() needs to be assigned to $x.
查看更多
成全新的幸福
7楼-- · 2019-03-20 21:23

I think you want to put

our $x;

into your code before accessing x. That will satisfy the strict error checking.

That being said, I join the other voices in suggesting Storable.

查看更多
登录 后发表回答