Как мне прочитать обратно в выводе Data :: Dumper? - PullRequest
5 голосов
/ 06 января 2009

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

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

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

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

eval $vars;

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

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

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

Ответы [ 9 ]

11 голосов
/ 06 января 2009

Вот тема, которая предоставляет несколько различных опций: Отменять

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

10 голосов
/ 07 января 2009

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

  • Сохраняемость - это быстро и просто, но достаточно специфично для 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);

8 голосов
/ 07 января 2009

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

$Data::Dumper::Purity = 1;

или

$obj->Purity(1);

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

См. документацию Data :: Dumper на CPAN для всех деталей.

5 голосов
/ 07 января 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;
3 голосов
/ 07 января 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.
1 голос
/ 06 июня 2009

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


# Load in the Dumper'ed library data structure and eval it
my $dsname = $ARGV[0];
my @lib = do "$dsname";
1 голос
/ 07 января 2009

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

Некоторые другие параметры: Storable, YAML или DBM :: Deep. Я перебираю некоторые примеры в главе «1001 * Мастеринг Perl .

» «Постоянство».

Удачи,:)

0 голосов
/ 07 января 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 $@;
0 голосов
/ 07 января 2009

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

our $x;

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

Как говорится, я присоединяюсь к другим голосам, предлагая Storable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...