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

发布于 2024-07-10 13:20:40 字数 549 浏览 5 评论 0原文

假设我有一个使用 Data::Dumper,大致如下:

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

我想读回该文件并获取 $x 。 我尝试了这个:

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

eval $vars;

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

全局符号 $x 需要明确的包名称。

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

云淡风轻 2024-07-17 13:20:40

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

就我个人而言,我认为我的目标是 YAML 或 JSON...没有比以下更简单的了:


我的 $data = YAML::Any::LoadFile($filename);

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

左岸枫 2024-07-17 13:20:40

这里有一个线程提供了几个不同的选项:Undumper

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

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.

人间不值得 2024-07-17 13:20:40

默认情况下,Data::Dumper 输出无法通过 eval 进行解析,特别是当转储的数据结构在某种程度上是循环的时。 但是,您可以设置

$Data::Dumper::Purity = 1;

$obj->Purity(1);

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

请参阅CPAN 上的 Data::Dumper 文档了解所有细节。

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.

感受沵的脚步 2024-07-17 13:20:40

正如 Rich 所说,您可能不想使用 Data::Dumper 来实现持久性,而是使用诸如 Storable 之类的东西。

但是,为了回答所提出的问题...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;

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;
旧情勿念 2024-07-17 13:20:40

如果您想保留一些简单且易于阅读的内容,只需使用 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

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.
送舟行 2024-07-17 13:20:40

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

其他一些选项包括 Storable、YAML 或 DBM::Deep。 我在掌握 Perl 的“持久性”一章中查看了一些示例。

祝你好运, :)

Are you sure that file was created by Data::Dumper? There shouldn't be a my in there.

Some other options are Storable, YAML, or DBM::Deep. I go through some examples in the "Persistence" chapter of Mastering Perl.

Good luck, :)

亢潮 2024-07-17 13:20:40

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


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

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";
分開簡單 2024-07-17 13:20:40

我认为您想

our $x;

在访问 x 之前将其放入代码中。 这将满足严格的错误检查。

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

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.

故事与诗 2024-07-17 13:20:40

这对我来说效果很好:

写出:

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 $@;

This works fine for me:

Writing out:

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

Reading in:

open(my $C, qw{<}, $userdatafile) or croak "$userdatafile: $!";
local $/ = $/;
my $str = <$C>;
close($C) || croak "$userdatafile: $!";
eval { $str };
croak $@ if $@;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文