2012-06-21 23 views
3

我使用Data :: Dumper將我的數據序列化爲Perl中的字符串。現在,在其他程序中,我嘗試使用eval反序列化它,我得到:

Global symbol "$VAR1" requires explicit package name 

我在我的程序中使用use warnings; use strict;

下面是我eval荷蘭國際集團代碼:

my $wiki_categories = eval($db_row->{categories}); 
die [email protected] if [email protected]; 
/* use $wiki_categories */ 

如何禁用我的程序死亡,因爲"$VAR1"沒有被宣佈爲my

我應該在eval之前追加"my "之前的$db_row->{categories}嗎?就像這樣:

my $wiki_categories = eval("my ".$db_row->{categories}); 

我還不測試,但我認爲這是可行的。

任何其他方式來做到這一點?也許把它包裝在一些塊中,並關閉該塊嚴格?我從來沒有做過,但我已經看到它提到。

任何幫助表示讚賞!

+0

Data :: Dumper是一個調試工具。你真的不應該用這種方式。 JSON是一個更好的選擇。 – ikegami

+0

這是一個後續http://stackoverflow.com/questions/11092658/how-do-i-serialize-an-array-of-array-references-in-perl – daxim

+0

你也可以只說'我的$ VAR1;的eval($ db_row - > {類別});我的$ wiki_categories = $ VAR1;'擺脫錯誤。但是那些已經存在的答案比那個更有幫助。閱讀並嘗試其他模塊進行數據存儲。 – simbabque

回答

8

這是正常的。默認情況下,當數據::自卸車數據序列化,它輸出類似:

$VAR1 = ...your data... 

使用數據::自卸車系列化,你需要配置它一點點。 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; 

你可以做各種花樣來縮小數據::自卸車的規模,但總體上它的快速和節省空間。主要的缺點是,它只是Perl而且非常不安全。如果任何人都可以修改你的轉儲文件,他們擁有你的程序。

CPAN上有模塊可以幫您處理這些問題,還有更多的模塊,比如Data::Serializer

6

你的問題有一些含義,我會盡量解決我的問題。

首先,讀取Data :: Dumper的perldoc。設置$Data::Dumper::Terse = 1可以滿足您的需求。全局變量中有很多選項,所以一定要對它們進行本地化。但是這改變了生產者而不是消費者的數據。我不知道你有多少控制。您的問題意味着您正在處理消費者,但沒有提及對生產者的任何控制。也許數據已經存在,你必須按原樣使用它。

下一個含義是你綁定到Data :: Dumper。同樣,數據可能已經存在,太糟糕了,請使用它。如果不是這種情況,我會建議切換到另一種可存儲格式。現在比較常見的是JSON。儘管JSON不是核心Perl的一部分,但安裝起來卻非常簡單。它也使這更容易。其中一個優點是數據在其他語言中也很有用。另一個是你避免eval STRING,如果數據受到損害,可能會輕易危及你的消費者。

下一個項目就是如何解決它的。例如,如果數據存在。一個簡單的解決方案就是像你一樣添加我的。這工作正常。另一個是剝離$ VAR1:(my $dumped = $db_row->{categories}) =~ s/^\s*\$\w+\s*=\s*//;。另一個是把「沒有警告」的權利納入評估:eval ("no warnings; no strict; " . $db_row->{categories});

就個人而言,我去與JSON只要有可能。

+0

若用DD作爲串行器,一個要使用純度= 1,這排除簡潔= 1。 – ikegami

2

您的代碼可以照原樣運作,但eval因爲$VAR1未在evaluse strict 'vars'範圍內未聲明而失效。

解決這個問題由緊塊地中禁用狹窄。 A do塊是否有這個技巧,像這樣

my $wiki_categories = do { 
    no strict 'vars'; 
    eval $db_row->{categories}; 
}; 
相關問題