Я сериализовал свои данные в Perl с помощью Data::Dumper. Теперь, когда я проверяю его, я получаю "Глобальный символ"$VAR1"требует явного имени пакета"
Я сериализовал свои данные в строку в Perl, используя Data::Dumper. Теперь в другой программе я пытаюсь десериализовать его с помощью eval
и я получаю:
Global symbol "$VAR1" requires explicit package name
я использую use warnings; use strict;
в моей программе.
Вот как я eval
в коде:
my $wiki_categories = eval($db_row->{categories});
die $@ if $@;
/* use $wiki_categories */
Как я могу отключить мою программу, умирающую из-за "$VAR1"
не объявляется как my
?
Должен ли я добавить "my "
перед $db_row->{categories}
в eval
? Как это:
my $wiki_categories = eval("my ".$db_row->{categories});
Я еще не проверял это, но думаю, что это сработает.
Есть ли другие способы сделать это? Возможно, заверните его в какой-нибудь блок и выключите строго для этого блока? Я никогда не делал это, но я видел, что упомянуто.
Любая помощь приветствуется!
3 ответа
Это нормально. По умолчанию, когда Data:: Dumper сериализует данные, он выводит что-то вроде:
$VAR1 = ...your data...
Чтобы использовать Data:: Dumper для сериализации, вам нужно немного его настроить. Terse
будучи наиболее важным параметром, он отключает $VAR
вещь.
use Data::Dumper;
my $data = {
foo => 23,
bar => [qw(1 2 3)]
};
my $dumper = Data::Dumper->new([]);
$dumper->Terse(1);
$dumper->Values([$data]);
print $dumper->Dump;
Тогда результат может быть передан прямо в переменную.
my $data = eval $your_dump;
Вы можете сделать разные трюки, чтобы уменьшить размер Data:: Dumper, но в целом это быстро и эффективно. Основным недостатком является то, что это только Perl и крайне небезопасно. Если кто-то может изменить ваш файл дампа, он владеет вашей программой.
В CPAN есть модули, которые позаботятся об этом за вас, и многое другое, например Data:: Serializer.
Ваш вопрос имеет ряд последствий, я постараюсь ответить на столько, сколько смогу.
Сначала прочитайте perldoc для Data::Dumper. настройка $Data::Dumper::Terse = 1
может быть достаточно для ваших нужд. Здесь есть много опций в глобальных переменных, поэтому обязательно их локализуйте. Но это меняет производителя, а не потребителя данных. Я не знаю, какой у тебя контроль над этим. Ваш вопрос подразумевает, что вы работаете с потребителем, но не упоминает о каком-либо контроле над производителем. Возможно, данные уже существуют, и вы должны использовать их как есть.
Следующим выводом является то, что вы привязаны к Data::Dumper. Опять же, данные могут уже существовать, так что очень плохо, используйте их. Если это не так, я бы рекомендовал перейти на другой сохраняемый формат. В наши дни довольно распространенным является JSON. Хотя JSON не является частью основного Perl, его установка довольно проста. Это также делает это намного проще. Одним из преимуществ является то, что данные полезны и на других языках. Другой способ заключается в том, что вы избегаете eval STRING, который в случае компрометации данных может легко скомпрометировать вашего потребителя.
Следующий пункт - как решить это как есть. Если данные существуют, например. Простое решение - просто добавить мой, как вы сделали. Это отлично работает. Еще один - убрать $VAR1: (my $dumped = $db_row->{categories}) =~ s/^\s*\$\w+\s*=\s*//;
, Другой - поместить "нет предупреждений" прямо в eval: eval ("no warnings; no strict; " . $db_row->{categories});
,
Лично я по возможности использую JSON.
Ваш код будет работать так, как он есть, за исключением того, что eval
не удается, потому что $VAR1
не объявлен в рамках eval
а также use strict 'vars'
в силе.
Обойти это, отключив стриктуры в максимально плотном блоке, насколько это возможно. do
блок делает свое дело, вот так
my $wiki_categories = do {
no strict 'vars';
eval $db_row->{categories};
};