2012-03-16 2 views
1

У меня есть программа, которая принимает структуру данных perl, которая предназначена для хранения данных. Есть ли способ проверить, является ли скаляр допустимым объектом Storable, не умирающим, если это не так?Безопасный скаляр для хранения совместимости

Например, если я:

use Storable qw(freeze thaw); 
my $ref = thaw("lol_not_storable") 

Я вернусь «Storable бинарного изображения v54.111 позже, чем я (v2.8) в /usr/local/lib/perl/5.12. 4/Storable.pm line 420, в строке test.pl 5 «

Я хотел бы выяснить, можно ли чисто обрабатывать эти исключения без eval. Возможно ли без перезаписывания накопительного модуля Perl?

+6

Что вы имеете против 'eval'? (Или один из его оберток, например [Try :: Tiny] (http://search.cpan.org/perldoc?Try::Tiny)? – cjm

+0

[»Вы не можете сделать это без проверки. Самый простой подход просто выполните декодирование и обработайте исключение. «] (http://stackoverflow.com/a/2583981/46395) – daxim

+0

@cjm Ничего, но я уже знал, как поймать эту ошибку с помощью eval. имеет раздел «Отчеты об ошибках» http://perldoc.perl.org/Storable.html, я надеялся на решение, которое его использовало. Я не смог заставить его работать сам. – GoldenNewby

ответ

3
eval { thaw("lol_not_storable"); }; 

это не то же самое, как

eval qq/thaw("lol_not_storable");/; 

в этом Perl имеет достаточно шансов, чтобы разобрать первый, но ждет, чтобы разобрать второй. Обратите внимание, ниже ошибка компиляции:

use 5.014; 
use strict; 
use warnings; 

say 'Would print without compile error'; 
eval { $i++; }; 
^D 

Global symbol "$i" requires explicit package name at - line 8. 
Execution of - aborted due to compilation errors. 

В то время как eval '$i++' не будет. Я думаю, что большая часть разочарования, которое вы слышали о eval, скорее относится к последнему типу, а не к первому. Последний оценивает строку как код, первый в основном говорит Perl «не умирайте».

Вот строка версии:

use 5.014; 
use strict; 
use warnings; 

say 'Would print without compile error'; 
eval ' $i++;'; 

Выходы:

Would print without compile error 

код по-прежнему не компилируется, но только тогда, когда это eval -ed, и только имеет эффект, когда я проверяю [email protected], который гласит:

[email protected]= 'Global symbol "$i" requires explicit package name at (eval 24) line 1. 
' 
0

Сделайте это с помощью магии :)

use Data::Dumper; 
use Storable qw(freeze thaw read_magic); 

my $storable_str = freeze([ 1 .. 42 ]); 
print Dumper(read_magic($storable_str)); 
# prints: 
# $VAR1 = { 
#  'netorder' => 0, 
#  'hdrsize' => 15, 
#  'version' => '2.7', 
#  'minor'  => 7, 
#  'longsize' => 8, 
#  'ptrsize' => 8, 
#  'version_nv' => '2.007', 
#  'byteorder' => '12345678', 
#  'major'  => 2, 
#  'intsize' => 4, 
#  'nvsize'  => 8 
# }; 

my $ordinary_str = join(',', (1 .. 42)); 
print Dumper(read_magic($ordinary_str)); 
# prints: 
# $VAR1 = undef; 

# So: 
if(read_magic($something_to_check)){ 
    my $ref = thaw($something_to_check); 
}else{ 
    # foo 
} 
Смежные вопросы