diagnostics, splain - 冗舌な診断警告の生成

目次


名前

diagnostics, splain - 冗舌な診断警告の生成


概要

diagnostics プラグマの使い方:

    use diagnostics;
    use diagnostics -verbose;

    enable  diagnostics;
    disable diagnostics;

splain スタンドアロンフィルタプログラムの使い方:

    perl program 2>diag.out
    splain [-v] [-p] diag.out

diagnostics を使って正常に動作しないスクリプトのスタックトレースを とる方法:

    perl -Mdiagnostics=-traceonly my_script.pl

説明

diagnostics プラグマ

このモジュールは perl コンパイラ及び perl インタプリタ双方から (-w スイッチをつけたり use warnings を使ったりしている時に) 発行される簡潔な診断を, perldiag にあるようなより説明的で より親切な説明を増やすことで拡張します. 他のプラグマのように 実行フェーズだけでなくプログラムのコンパイルフェーズにも 効果を持ちます.

プログラム中でプラグマとして使うには, 単純に

    use diagnostics;

とプログラムの始まり(若しくは始まり近く)で呼び出します. (これは perl の -w フラグを有効にすることに注意して 下さい.) あなたのコンパイル全体が強化された診断の支配下に 置かれるようになります. 診断は STDERR に出力されます.

実行時とコンパイル時の間の相互作用によって, そしてそれは どのみちあまりよいアイデアではないために, 実行時に診断メッセージ を消すために no diagnostics をは使えないでしょう. しかしながら, disable() 及び enable() メソッドを使って 実行時にその振る舞いを制御することは可能です.

-verbose フラグははじめに他の診断に先立って perldiag の紹介を 出力します. $diagnostics::PRETTY 変数でページャ用のよりよい エスケープシーケンスを生成することができます.

perl 自身から発行される警告(またはより正確には, perldiag で 見つけることができる説明とマッチするもの)は, 一度だけ 表示されます(説明は重複しません). warn() のように警告を生成する ユーザのコードには影響しないので, ユーザがメッセージを重複して 表示させることは妨げません.

このモジュールは perl が die したときにエラーメッセージにスタック トレースを追加することも行います. これは何が死因だったのかを ピンポイントに探り当てるのに便利です. -traceonly (若しくは単に -t) フラグはスタックトレースは有効にしたまま警告メッセージの 説明を切ります. なので, スクリプトが die するときには

  perl -Mdiagnostics=-traceonly my_bad_script

を指定してもう一度実行することで死亡時のコールスタックを見ることが できます. <-warntrace> (若しくは単に -w)フラグを使うことで すべての警告でスタックトレースが付与されます.

splain プログラム

nuther なプログラムの全体を見てみても, 実際 splaindiagnostics.pod ドキュメントへのリンクと同様に(実行可能な) diagnostics.pm へのリンク以上の何者でもありません. -v フラグは use diagnostics -verbose ディレクティブのような ものです. -p フラグは $diagnostics::PRETTY 変数のようなものです. splain で後処理をしているので処理を enable() 若しくは disable() を行う意味はありません.

splain の出力はプラグマとは違って STDOUT に出力されます.


次のファイルはいくつかのエラーを実行時とコンパイル時に 発生させます:

    use diagnostics;
    print NOWHERE "nothing\n";
    print STDERR "\n\tThis message should be unadorned.\n";
    warn "\tThis is a user warning";
    print "\nDIAGNOSTIC TESTER: Please enter a <CR> here: ";
    my $a, $b = scalar <STDIN>;
    print "\n";
    print $x/$y;

まず先にプログラムを実行して問題を見ておきたいのなら 次のようにします:

    perl -w test.pl 2>test.out
    ./splain < test.out

これは継承のより怪しいシェルでは一般的な方法ではありませんが, 理論的には:

    (perl -w test.pl >/dev/tty) >& test.out
    ./splain < test.out

なぜなら既存の stdout をどこか別のところにやっているからです.

ソースコードをいじりたくないけれど警告を on-the-fly にとりたいの であれば次のようにします:

    exec 3>&1; perl -w test.pl 2>&1 1>&3 3>&- | splain 1>&2 3>&-

すごいでしょ?

もし警告を on the fly に制御したいのならこのような何かを 行います. 最初に use します, これがないと enable() 及び disable() メソッドを使えません.

    use diagnostics; # checks entire compilation phase 
	print "\ntime for 1st bogus diags: SQUAWKINGS\n";
	print BOGUS1 'nada';
	print "done with 1st bogus\n";

    disable diagnostics; # only turns off runtime warnings
	print "\ntime for 2nd bogus: (squelched)\n";
	print BOGUS2 'nada';
	print "done with 2nd bogus\n";

    enable diagnostics; # turns back on runtime warnings
	print "\ntime for 3rd bogus: SQUAWKINGS\n";
	print BOGUS3 'nada';
	print "done with 3rd bogus\n";

    disable diagnostics;
	print "\ntime for 4th bogus: (squelched)\n";
	print BOGUS4 'nada';
	print "done with 4th bogus\n";

内部動作

診断メッセージは実行時に perldiag.pod ファイルから派生します. それ以外は splain パッケージがビルドされたときにファイルに 埋め込まれています. 詳細は Makefile を見てください.

既存の $SIG{__WARN__} ハンドラが見つかっても, 誠実に継続しますが それは diagnostics::splainthis() 関数(このモジュールの $SIG{__WANR__} インターセプタ)が警告にその手段を持ったときだけです.

もし何がインターセプトされているのかを猛烈に知りたいのであれば, $diagnostics::DEBUG 変数を設定してみるとよいでしょう.

    BEGIN { $diagnostics::DEBUG = 1 }

バグ

"no diagnostics" を使えないことは悩ましいですがおそらく乗り越え られないでしょう.

-pretty ディレクティブは状況に影響を与えるには呼び出すのが 遅すぎます. 代わりにモジュールをロードする前に次のことを 行う必要があります.

    BEGIN { $diagnostics::PRETTY = 1 }

必要になるまでコンパイルを遅延させることで起動を高速にできますが, これは Perl 5.001e においてプラグマ形式を使ったとき "panic: top_level" を発生させます.

ドキュメントは重要に準じるものであるので, splain プログラムを 使うのならいくぶん奇抜さを予測しておくべきです.


著者

Tom Christiansen <tchrist@mox.perl.com>, 25 June 1995.


和訳

 山科 氷魚 (YAMASHINA Hio) <hio@hio.jp>

原典: perl VERSION 5.8.8. 翻訳日: 2007-03-16.

diagnostics, splain - 冗舌な診断警告の生成

索引

diagnostics, splain - 冗舌な診断警告の生成