2012-03-16 62 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 
}