=head1 名前 diagnostics, splain - 冗舌な診断警告の生成 =head1 概要 C プラグマの使い方: use diagnostics; use diagnostics -verbose; enable diagnostics; disable diagnostics; C スタンドアロンフィルタプログラムの使い方: perl program 2>diag.out splain [-v] [-p] diag.out diagnostics を使って正常に動作しないスクリプトのスタックトレースを とる方法: perl -Mdiagnostics=-traceonly my_script.pl =head1 説明 =head2 C プラグマ このモジュールは perl コンパイラ及び perl インタプリタ双方から (-w スイッチをつけたり C を使ったりしている時に) 発行される簡潔な診断を, L にあるようなより説明的で より親切な説明を増やすことで拡張します. 他のプラグマのように 実行フェーズだけでなくプログラムのコンパイルフェーズにも 効果を持ちます. プログラム中でプラグマとして使うには, 単純に use diagnostics; とプログラムの始まり(若しくは始まり近く)で呼び出します. (これは perl の B<-w> フラグを有効にI<する>ことに注意して 下さい.) あなたのコンパイル全体が強化された診断の支配下に 置かれるようになります. 診断は B に出力されます. 実行時とコンパイル時の間の相互作用によって, そしてそれは どのみちあまりよいアイデアではないために, 実行時に診断メッセージ を消すために C をは使えないでしょう. しかしながら, disable() 及び enable() メソッドを使って 実行時にその振る舞いを制御することは可能です. B<-verbose> フラグははじめに他の診断に先立って L の紹介を 出力します. $diagnostics::PRETTY 変数でページャ用のよりよい エスケープシーケンスを生成することができます. perl 自身から発行される警告(またはより正確には, L で 見つけることができる説明とマッチするもの)は, 一度だけ 表示されます(説明は重複しません). warn() のように警告を生成する ユーザのコードには影響しないので, ユーザがメッセージを重複して 表示させることは妨げません. このモジュールは perl が die したときにエラーメッセージにスタック トレースを追加することも行います. これは何が死因だったのかを ピンポイントに探り当てるのに便利です. B<-traceonly> (若しくは単に B<-t>) フラグはスタックトレースは有効にしたまま警告メッセージの 説明を切ります. なので, スクリプトが die するときには perl -Mdiagnostics=-traceonly my_bad_script を指定してもう一度実行することで死亡時のコールスタックを見ることが できます. <-warntrace> (若しくは単に B<-w>)フラグを使うことで すべての警告でスタックトレースが付与されます. =head2 I プログラム nuther なプログラムの全体を見てみても, 実際 I は F ドキュメントへのリンクと同様に(実行可能な) F へのリンク以上の何者でもありません. B<-v> フラグは B ディレクティブのような ものです. B<-p> フラグは $diagnostics::PRETTY 変数のようなものです. I で後処理をしているので処理を enable() 若しくは disable() を行う意味はありません. I の出力はプラグマとは違って B に出力されます. =head1 例 次のファイルはいくつかのエラーを実行時とコンパイル時に 発生させます: 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 here: "; my $a, $b = scalar ; 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 なぜなら既存の B をどこか別のところにやっているからです. ソースコードをいじりたくないけれど警告を on-the-fly にとりたいの であれば次のようにします: exec 3>&1; perl -w test.pl 2>&1 1>&3 3>&- | splain 1>&2 3>&- すごいでしょ? もし警告を on the fly に制御したいのならこのような何かを 行います. 最初に C します, これがないと 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"; =head1 内部動作 診断メッセージは実行時に F ファイルから派生します. それ以外は splain パッケージがビルドされたときにファイルに 埋め込まれています. 詳細は F を見てください. 既存の $SIG{__WARN__} ハンドラが見つかっても, 誠実に継続しますが それは diagnostics::splainthis() 関数(このモジュールの $SIG{__WANR__} インターセプタ)が警告にその手段を持ったときだけです. もし何がインターセプトされているのかを猛烈に知りたいのであれば, $diagnostics::DEBUG 変数を設定してみるとよいでしょう. BEGIN { $diagnostics::DEBUG = 1 } =head1 バグ "no diagnostics" を使えないことは悩ましいですがおそらく乗り越え られないでしょう. C<-pretty> ディレクティブは状況に影響を与えるには呼び出すのが 遅すぎます. 代わりにモジュールをロードするI<前に>次のことを 行う必要があります. BEGIN { $diagnostics::PRETTY = 1 } 必要になるまでコンパイルを遅延させることで起動を高速にできますが, これは Perl 5.001e においてプラグマ形式を使ったとき "panic: top_level" を発生させます. ドキュメントは重要に準じるものであるので, I プログラムを 使うのならいくぶん奇抜さを予測しておくべきです. =head1 著者 Tom Christiansen >, 25 June 1995. =head1 和訳 山科 氷魚 (YAMASHINA Hio) 原典: perl VERSION 5.8.8. 翻訳日: 2007-03-16.