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
运行 Perl 时)通常发出的简短诊断信息,用 perldiag 中更具解释性和更具吸引力的描述来增强它们。与其他编译指示一样,它影响程序的编译阶段,而不仅仅是执行阶段。
要在您的程序中用作编译指示,只需调用
use diagnostics;
在程序的开头(或接近开头)。(请注意,这确实启用了 perl 的-w标志。)然后您的整个编译将受到增强诊断的约束(: -))。这些仍然输出到STDERR。
由于运行时和编译时问题之间的交互,并且因为它可能不是一个好主意,因此您不能使用no diagnostics
在编译时将其关闭。但是,您可以使用 disable() 和 enable() 方法分别在运行时控制其行为,以将其关闭和打开。
-verbose标志首先打印出perldiag介绍,然后再打印任何其他诊断信息。$diagnostics::PRETTY 变量可以为寻呼机生成更漂亮的转义序列。
从 perl 本身(或更准确地说,那些与perldiag中找到的描述匹配的警告)仅显示一次(没有重复的描述)。用户代码生成的警告 a la warn() 不会受到影响,允许显示重复的用户消息。
此模块还在 perl 死亡时将堆栈跟踪添加到错误消息中。这对于查明导致死亡的原因很有用。-traceonly(或仅-t)标志关闭警告消息的解释,只留下堆栈跟踪。因此,如果您的脚本正在死亡,请使用以下命令再次运行它
perl -Mdiagnostics=-traceonly my_bad_script
查看死亡时的调用堆栈。通过提供-warntrace(或仅-w)标志,任何发出的警告也将附带堆栈跟踪。
另一个程序splain实际上只是对(可执行的)diagnostics.pm模块的链接,以及对diagnostics.pod文档的链接。-v标志类似于use diagnostics -verbose
指令。-p标志类似于$diagnostics::PRETTY 变量。由于您使用splain进行后处理,因此没有意义能够启用() 或禁用() 处理。
与编译指示不同,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
请注意,这在一般情况下在血统更可疑的 shell 中是不可能的,因为理论上
(perl -w test.pl >/dev/tty) >& test.out
./splain < test.out
因为您只是将现有的stdout移动到了其他地方。
如果您不想修改源代码,但仍然需要即时警告,请执行以下操作
exec 3>&1; perl -w test.pl 2>&1 1>&3 3>&- | splain 1>&2 3>&-
很巧妙,对吧?
如果您想即时控制警告,请执行以下操作。确保您首先执行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{__WARN__} 拦截器)对您的警告进行处理之后。
如果您非常想知道正在拦截哪些内容,可以设置一个 $diagnostics::DEBUG 变量。
BEGIN { $diagnostics::DEBUG = 1 }
无法说“no diagnostics”很烦人,但这可能并非不可克服。
-pretty
指令调用得太晚,无法影响此事。您必须这样做,并且在加载模块之前。
BEGIN { $diagnostics::PRETTY = 1 }
我可以通过延迟编译直到需要它来更快地启动,但这在 Perl 5.001e 中使用 pragma 形式时会得到“panic: top_level”。
虽然这份文档确实有点不严肃,但如果您使用名为splain的程序,您应该期待一些奇思妙想。
Tom Christiansen <[email protected]>,1995 年 6 月 25 日。