Как прочитать вывод Data::Dumper?

Допустим, у меня есть текстовый файл, созданный с помощью Data::Dumper, в строках:

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

Я хотел бы снова прочитать этот файл и вернуть $x. Я пробовал это:

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

eval $vars;

Но это не сработало -- $x не только не определено, когда я пытаюсь его использовать, я получаю предупреждение, что

Глобальный символ $x требует явного имени пакета.

Как правильно это сделать? (И да, я знаю, что это уродливо. Это быстрый служебный скрипт, а не, например, система жизнеобеспечения.)


person mike    schedule 06.01.2009    source источник
comment
Data::Dumper не очень хороший выбор для хранения данных. Это скорее инструмент отладки.   -  person Paul Tomblin    schedule 06.01.2009


Ответы (9)


Вот ветка, предлагающая несколько разных вариантов: Undumper

Если вы просто ищете постоянство данных, модуль Storage может быть вашим лучшим выбором.

person Rich Reuter    schedule 06.01.2009

Как уже говорили другие, вам, вероятно, лучше хранить данные в лучшем формате сериализации:

  • Storable — это быстро и просто, но довольно специфично для Perl (но удовлетворит ваши потребности в быстрое решение в относительно неважном сценарии легко)
  • YAML, используя YAML или YAML::Tiny , или YAML::Any в качестве оболочки, позволяющей использовать преимущества любых модулей JSON. ) доступны в вашей системе
  • JSON, используя JSON или JSON::XS для большей скорости (или JSON::Any в качестве оболочки, позволяющей использовать преимущества любого JSON модуль (модули) доступны в вашей системе)
  • XML с помощью модуля XML-Simple или одного из других модулей XML.

Лично я думаю, что я бы стремился к YAML или JSON... вы не можете быть намного проще, чем:

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

person David Precious    schedule 06.01.2009
comment
модуль JSON теперь будет использовать JSON::XS по умолчанию, если он установлен в системе - person plusplus; 30.03.2010

По умолчанию выходные данные Data::Dumper не могут быть проанализированы с помощью eval, особенно если выгружаемая структура данных каким-то образом циклична. Однако вы можете установить

$Data::Dumper::Purity = 1;

or

$obj->Purity(1);

где obj — объект Data::Dumper. Любой из них приведет к тому, что Data::Dumper выдаст результат, который может быть проанализирован eval.

Смотрите документацию Data::Dumper на CPAN, Детали.

person Dale Hagglund    schedule 06.01.2009

Как говорит Рич, вы, вероятно, не хотите использовать Data::Dumper для сохраняемости, а скорее что-то вроде Storable.

Однако, чтобы ответить на заданный вопрос... IIRC, Data::Dumper не объявляет ваши переменные как my, так что вы как-то сами это делаете?

Чтобы иметь возможность eval вернуть данные, переменная не должна быть my в eval. Если ваш текстовый файл содержит это:

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

Тогда это сработает:

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

my $x;    
eval $vars;
print $x;
person Adam Bellaire    schedule 06.01.2009

Если вы хотите использовать что-то простое и понятное для человека, просто используйте 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.
person j_random_hacker    schedule 07.01.2009

Вы уверены, что файл был создан Data::Dumper? Там не должно быть my.

Некоторые другие варианты: «Сохраняемый», «YAML» или «DBM::Deep». Я рассматриваю несколько примеров в главе «Постоянство» книги Mastering Perl.

Удачи, :)

person brian d foy    schedule 06.01.2009

Этот фрагмент короткий и работал у меня (я читал в массиве). Он берет имя файла из первого аргумента скрипта.


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

Я думаю, ты хочешь поставить

our $x;

в свой код перед доступом к x. Это удовлетворит строгую проверку ошибок.

При этом я присоединяюсь к другим голосам, предлагающим Storeable.

person Community    schedule 06.01.2009

Это отлично работает для меня:

Выписывание:

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 $@;
person Glen Solsberry    schedule 06.01.2009