2007年2月9日金曜日

B::Deparse + Storable

というわけで

404 Blog Not Found perl - B::Deparse

B::Deparseというモジュールがすごく便利だということがわかったわけですが、気になったところが。

実はData::DumperもStorableも、B::Deparseをサポートしている。これらを利用すると、code referenceを普通のオブジェクトのように扱ったり、シリアライズしたりすることが簡単に出来る。詳しくはそれぞれのマニュアルを参照のこと。

個人的にStorableは非常に重宝しているモジュールなのだが、GLOB型やCODE REFERENSEはシリアライズできない仕様になっております。
なのだが、この記事を見てからさっそくStorableのpodをみてみたところ、それらしき記述を発見。
というわけで以下のようなスクリプトを作ってためしてみました。(ってほとんどStorableのpodどおりだけど)
nstore
#!/usr/bin/perl

use strict;
use Storable qw(nstore);
use Safe;

my $safe = new Safe;
$safe->permit(qw(:default require));
# まあたかだか簡単なスクリプトなのでlocalはいらないかもだけど
local $Storable::Deparse = 1;
local $Storable::Eval = sub { $safe->reval($_[0]) };
my $code = sub { print "hello\n" };
nstore( $code, shift );


retrieve
#!/usr/bin/perl

use strict;
use Storable;
use Safe;

my $safe = new Safe;
$safe->permit(qw(:default require));
local $Storable::Eval = sub { $safe->reval($_[0]) };
my $code = retrieve(shift);
$code->();

nstoreとretrieveという2つのPerlスクリプトを作成してから
perl nstore シリアライズした情報を保存するファイル名

でcode referenceを保存。次にretireveでシリアライズしたファイルからデシリアライズする。
perl retrieve シリアライズした情報を保存したファイル名

を実行すると下記のとおり、
hello

見事code referenceを復元できて実行することができました。これは今後かなり重宝しそうな技なので覚えておいて損はしないと思います。いやはや、B::Deparseに感謝感謝

というわけでPerlのテクニックがいろいろ満載されていそうなこの本がぜひぜひほしいところです。



Perlベストプラクティス