5

永続的/キャッシュされたスクリプトを作成しようとしています。コードは次のようになります。

...
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;
}

次のようにループ内のシェルスクリプトから呼び出されます

value=`perl my_script.pl`;

このスクリプトをその状態を維持するように呼び出す方法はありますか? コールからコールへ。'%my_hash' の初期化と extract_values_from_file の呼び出しの両方がコストのかかる操作であると仮定しましょう。

ありがとう

4

4 に答える 4

13

これは一種の黒魔術ですが、スクリプトの__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ブロックはコンパイルフェーズ中に設定されません。

于 2012-04-27T15:21:06.340 に答える
6

例の %my_hash が最終的な初期化状態で中程度のサイズである場合、StorableJSON::XSまたはData:: Dumper などのシリアル化モジュールのいずれかを使用して、実行間でデータを事前に組み立てられた形式に保つことができます。存在しない場合は新しいファイルを生成し、存在する場合はそこから準備完了のコンテンツをリロードします。

また、このスクリプトをループで呼び出すと述べました。適切な戦略は、スクリプトをループ内ですぐに呼び出すのではなく、代わりに引数のキューを作成し、それらすべてをループの後でスクリプトに 1 回の実行で渡すことです。スクリプトは環境をセットアップし、引数ごとにループして簡単な作業を行い、それぞれのセットアップ手順をやり直す必要はありません。

于 2012-04-27T14:27:11.057 に答える
2

スクリプトに状態を保持させることはできません。プロセスが存在するとすぐに、ディスクに書き込まれていない情報はなくなります。

ただし、これを実現する方法がいくつかあります。

  • ネットワークまたは UNIX ソケットをリッスンするデーモンを作成します。デーモンはmy_hash、非常に単純なmy_script.pl. デーモンへの接続を開き、質問を送信して回答を返すだけで済みます。

  • 効率的なルックアップ ファイル形式を作成します。情報が頻繁に必要な場合は、とにかく VFS キャッシュに残っている可能性があります。

  • 共有メモリ領域を設定します。スクリプトを初めて開始するときに、そこに情報を保存し、後で再利用します。ただし、Perl スクリプトでは扱いにくいかもしれません。

于 2012-04-27T14:22:24.113 に答える
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.

凍結/解凍でも同じことができます

于 2012-04-27T14:32:48.583 に答える