2012-03-16 70 views
1

我有一个程序,它接受一个perl数据结构,它是一个可存储的标量。有没有一种方法来测试标量是否是一个有效的Storable对象,如果不是,它将不会死亡?安全地测试标量为可存储的兼容性

举例来说,如果我这样做:

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

我回来“可存储二进制图像v54.111更近的比我(V2.8)在/usr/local/lib/perl/5.12。 4/Storable.pm line 420,at test.pl line 5“

我想弄清楚是否有可能在没有eval的情况下干净地处理这些异常。有没有可能重写可存储的Perl模块?

+6

你有什么反对'eval'? (或者其中一个包装,像[Try :: Tiny](http://search.cpan.org/perldoc?Try::Tiny)? – cjm 2012-03-16 09:22:02

+0

[»你不能没有检查就做到这一点,最简单的方法是只是做解码,然后处理异常«](http://stackoverflow.com/a/2583981/46395) – daxim 2012-03-16 10:27:48

+0

@cjm没有什么真正的,但我已经意识到如何捕捉与eval这个错误。有一个“错误报告”部分http://perldoc.perl.org/Storable.html,我希望有一个解决方案可以使用它,但我无法让它自己工作。 – GoldenNewby 2012-03-17 00:37:36

回答

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 
}