假设我有一个使用Data::Dumper
创建的文本文件,其行如下:
my $x = [ { foo => 'bar', asdf => undef }, 0, -4, [ [] ] ];
我想重新阅读该文件并获取$x
。我试过这个:
my $vars;
{
undef $/;
$vars = <FILE>;
}
eval $vars;
但它似乎没有用 - $x
不仅没有定义,当我尝试使用它时,我收到警告
全局符号$ x需要显式包名。
这样做的正确方法是什么? (是的,我知道这很难看。它是一个快速的实用程序脚本,而不是一个生命支持系统。)
答案 0 :(得分:11)
这是一个提供两个不同选项的主题: Undumper
如果你只是在寻找数据持久性,那么Storable模块可能是你最好的选择。
答案 1 :(得分:10)
正如其他人已经说过的那样,您可能最好以更好的序列化格式存储数据:
就个人而言,我认为我的目标是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;
请注意
$/
分配到自己的块中,则应使用local
确保其值在块结束时实际恢复;和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 $@;