我如何回读Data :: Dumper的输出?

时间:2009-01-06 20:35:52

标签: perl persistence data-dumper

假设我有一个使用Data::Dumper创建的文本文件,其行如下:

my $x = [ { foo => 'bar', asdf => undef }, 0, -4, [ [] ] ];

我想重新阅读该文件并获取$x。我试过这个:

my $vars;
{
  undef $/;
  $vars = <FILE>;
}

eval $vars;

但它似乎没有用 - $x不仅没有定义,当我尝试使用它时,我收到警告

  

全局符号$ x需要显式包名。

这样做的正确方法是什么? (是的,我知道这很难看。它是一个快速的实用程序脚本,而不是一个生命支持系统。)

9 个答案:

答案 0 :(得分:11)

这是一个提供两个不同选项的主题: Undumper

如果你只是在寻找数据持久性,那么Storable模块可能是你最好的选择。

答案 1 :(得分:10)

正如其他人已经说过的那样,您可能最好以更好的序列化格式存储数据:

  • Storable - 这是快速而简单的,但相当Perl特定(但很容易满足您对相对不重要的脚本快速解决方案的需求)
  • YAML,使用YAML模块或YAML::TinyYAML::Any作为包装,以利用系统上可用的任何JSON模块< / LI>
  • JSON,使用JSON模块,或JSON::XS以获得更快的速度(或JSON::Any作为包装,以利用任何可用的JSON模块你的系统)
  • XML,使用XML-Simple模块或其他XML模块之一。

就个人而言,我认为我的目标是YAML或JSON ...你不能比以下更容易:

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

答案 2 :(得分:8)

默认情况下,eval不能解析Data :: Dumper输出,特别是如果转储的数据结构在某种程度上是循环的。但是,您可以设置

$Data::Dumper::Purity = 1;

$obj->Purity(1);

其中obj是Data :: Dumper对象。其中任何一个都会导致Data :: Dumper生成可以通过eval解析的输出。

有关所有详细信息,请参阅the Data::Dumper documenatation at CPAN

答案 3 :(得分:5)

正如里奇所说,你可能不想使用Data :: Dumper来保持持久性,而是喜欢可以存储

然而,为了回答问题...... IIRC,Data :: Dumper没有声明你的变量是my,所以你自己也是这样做的吗?

为了能够eval数据重新进入,变量不需要在eval中my。如果您的文本文件包含以下内容:

$x = [ { foo => 'bar', asdf => undef }, 0, -4, [ [] ] ];

然后这会起作用:

my $vars;
{
  undef $/;
  $vars = <FILE>;
}

my $x;    
eval $vars;
print $x;

答案 4 :(得分:3)

如果您希望保持简单且易于阅读的内容,只需使用Data::Dump模块而不是Data::Dumper。基本上,它是Data::Dumper完成的 - 它生成有效的Perl表达式,可以进行赋值,而不会创建所有那些奇怪的$VAR1$VAR2等变量。

然后,如果您的代码如下:

my $x = [ { foo => 'bar', asdf => undef }, 0, -4, [ [] ] ];

使用以下方式保存:

use Data::Dump "pp";
open F, ">dump.txt";
print F pp($x);

这会产生一个看起来像dump.txt的文件(至少在我的电脑上):

[{ asdf => undef, foo => "bar" }, 0, -4, [[]]]

使用以下方式加载:

open F, "dump.txt";
my $vars;
{ local $/ = undef; $vars = <F>; }
my $x = eval $vars;

请注意

  1. 如果您正忙于将$/分配到自己的块中,则应使用local确保其值在块结束时实际恢复;和
  2. 需要将eval()的结果分配给$x

答案 5 :(得分:1)

你确定该文件是由Data :: Dumper创建的吗?那里不应该有my

其他一些选项包括Storable,YAML或DBM :: Deep。我在Mastering Perl的“持久性”一章中介绍了一些例子。

祝你好运,:))

答案 6 :(得分:1)

这段代码简短,对我有用(我正在阅读数组)。它从第一个脚本参数中获取文件名。


# Load in the Dumper'ed library data structure and eval it
my $dsname = $ARGV[0];
my @lib = do "$dsname";

答案 7 :(得分:0)

我想你想放

our $x;
在访问x之前

进入代码。这将满足严格的错误检查。

话虽这么说,我和其他人一起建议Storable。

答案 8 :(得分:0)

这对我来说很好用:

写出:

open(my $C, qw{>}, $userdatafile) or croak "$userdatafile: $!";
use Data::Dumper;
print $C Data::Dumper->Dump([\%document], [qw(*document)]);
close($C) || croak "$userdatafile: $!";

阅读:

open(my $C, qw{<}, $userdatafile) or croak "$userdatafile: $!";
local $/ = $/;
my $str = <$C>;
close($C) || croak "$userdatafile: $!";
eval { $str };
croak $@ if $@;