2012-04-27 31 views
4

我正在嘗試編寫一個持久性/高速緩存的腳本。該守則將是這個樣子:編寫持久性perl腳本

... 
Memoize('process_fille'); 
print process_file($ARGV[0]); 
... 
sub process_file{ 
    my $filename = shift; 
    my ($a, $b, $c) = extract_values_from_file($filename); 
    if (exists $my_hash{$a}{$b}{$c}){ 
     return $my_hash{$a}{$b}{$c}; 
    } 
    return $default; 
} 

這將在shell腳本在一個循環中調用如下

value=`perl my_script.pl`; 

有沒有一種方法,我可以把這個腳本以這樣一種方式,它將保持其狀態。從呼叫到呼叫。讓我們假設初始化'%my_hash'和調用extract_values_from_file是一個昂貴的操作。

謝謝

+1

IMO取決於腳本的使用頻率。如果它只是偶爾運行,請使用序列化技術。如果它不止於此 - 例如它正在服務某種關鍵的或許是實時的相對目的 - 使它成爲一個持久的後臺服務器/使用IPC。 – delicateLatticeworkFever 2012-04-27 17:51:28

回答

6

如果在你的榜樣%my_hash在其最後的初始化狀態大小適中,你可以簡單地使用的序列化模塊中的一個像StorableJSON::XSData::Dumper,讓您的數據在運行之間的預組裝形式。生成一個新文件,當它不存在時,只要從那裏重新加載準備好的內容。

此外,你已經提到你可以在循環中調用這個腳本。一個好的策略是不要在循環中立即調用腳本,而是建立一個參數隊列,然後在單次執行循環後將所有參數傳遞給腳本。腳本會設置它的環境,然後循環參數進行簡單的工作,而無需爲每個腳本重新設置步驟。

2

你不能讓腳本保持狀態。只要進程存在,任何未寫入磁盤的信息都將消失。

有您能做到這一點,雖然幾個方面:

  • 寫監聽網絡或Unix套接字上的後臺。守護進程可以填充my_hash並回答從簡單的my_script.pl發送的問題。它只需要打開與守護進程的連接,發送問題並返回答案。

  • 創建一個有效的查找文件格式。如果您經常需要這些信息,它可能仍會保留在VFS緩存中。

  • 設置共享內存區域。腳本第一次啓動時,將信息保存在那裏,稍後重新使用。儘管如此,Perl腳本可能會很棘手。

0

不是,但可以通過很多方式實現。

1) I understand **extract_values_from_file()** parses given file returning hash. 
2) 1 can be made as a script, then dump the parsed hash using **Data::Dumper** into file. 
3) When running my_script.pl, ensure that file generated by 2 is later than of the config file. Can achieve this via **make** 
3.1) **use** the file generated by 2 to retrieve values. 

同樣可以通過冷凍/解凍

8

實現這是一種黑暗魔法,但你可以在將腳本的__DATA__令牌存儲狀態和堅持它。

use Data::Dumper; # or JSON, YAML, or any other data serializer 
package MyPackage; 
my $DATA_ptr; 
our $state; 
INIT { 
    $DATA_ptr = tell DATA; 
    $state = eval join "", <DATA>; 
} 

... 
manipulate $MyPackage::state in this and other scripts 
... 

END { 
    open DATA, '+<', $0; # $0 is the name of this script 
    seek DATA, $DATA_ptr, 0; 
    print DATA Data::Dumper::Dumper($state); 
    truncate DATA, tell DATA; # in case new data is shorter than old data 
    close DATA; 
} 
__DATA__ 
$VAR1 = { 
    'foo' => 123, 
    'bar' => 42, 
    ... 
} 

INIT塊,存儲你的文件的__DATA__節開頭的位置和反序列化狀態。在END塊中,您將重新串行化當前狀態並覆蓋腳本的__DATA__部分。當然,運行腳本的用戶需要對腳本擁有寫入權限。

編輯爲使用INIT塊而不是BEGIN塊 - DATA塊在編譯階段未設置。

+5

序列化狀態 - 是的。重寫它在你自己 - 大大該死的不!這可能看起來很時髦,會產生一兩個或兩個,但它是一個完整的混亂維護。 – 2012-04-27 15:32:40

+3

非常酷,但打印到您的實際源代碼文件似乎不健康。 – TLP 2012-04-27 17:24:17