■2006-02-08
* [Per][メモ] XSモジュールのSTDERRをキャプチャする
変数内部を覗くに便利なDevel::Peek。問答無用でSTDERRに出力されます(perl内部のルーチン経由)。このSTDERRに出力されたデータを別ハンドルにリダイレクトしようとして知ったのですが、open my $fh, '>', \$var; *STDERR = $fhみたいな方法ではXSモジュールのSTDOUTやSTDERRをリダイレクトできないんですね(PerlIOを経由しないからかしら?)(→追記:PerlIO経由のみなら大丈夫であることをコメント欄で教えていただきました)。例えばIO::Captureを使って
use IO::Capture::Stderr;
my $capture = IO::Capture::Stderr->new();
$capture->start();
Dump("a"); # STDERRに出力される……
print STDERR "foo!";
$capture->stop();
print "stderr : ", $capture->read;
とやっても、foo!しか取得できません。それでpipeとforkを使って子プロセスにDevel::Peek::Dumpを実行させ、パイプ経由で親プロセスが出力を回収するモジュールを書いたのですが、CPANにはIO::CaptureOutputというモジュールがありました。このモジュールは一時ファイルを利用してサブプロセスやXSモジュールのSTDOUT, STDERRを変数にキャプチャします。
このモジュールを(そのままでは不都合があるので)少し弄くってつくったDevel::Peek::Capture。Devel::Peekと同じDumpがインポートされます。
use Devel::Peek::Capture;
my $foo = {};
my $output = Dump($foo);
print $output;
おまけで、ある変数が threads::shared で共有化されているかどうかを判定する is_shared がついてます。
[]

