トップ «前の日記(■2006-02-05) 最新 次の日記(■2006-02-16)» 編集

どんぞこ日誌

2003|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|07|08|12|
2007|01|04|08|12|
2008|01|02|03|04|06|07|08|10|11|12|
2009|01|02|04|05|06|07|08|09|11|12|
2010|01|03|04|07|08|10|11|12|
2011|01|02|03|04|05|06|07|08|10|12|
2012|01|02|03|05|06|07|08|09|10|
2013|01|02|07|08|09|
2014|08|09|
2015|08|
2016|06|07|12|
2017|01|03|08|
2018|03|
2022|03|
2023|03|
2024|02|

同人関連(どんぞこ楽屋) | 旧い雑文   


■2006-02-08

* [Per][メモ] XSモジュールのSTDERRをキャプチャするB!

  変数内部を覗くに便利な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 がついてます。

本日のツッコミ(全2件) [ツッコミを入れる]
_ H.Inaba (■2006-02-08 15:22)

PerlIO経由だけであれば、一時ファイルがなくともできますね。<br><br>use Devel::Peek;<br>my $stderr; close STDERR;<br>open STDERR, ">", \$stderr or die $!;<br>Dump {Foo=>1, Bar=>2};<br>print "stderr:{$stderr}\n"'

_ まかまか (■2006-02-08 15:52)

あ、ほんとだ。<br>簡単なデバッグ用ならこっちの方で良いですね。

[]