我希望有致命的错误,可以降级为警告(或相反,警告可以提升为致命错误),具体取决于用户的偏好。目前,我正在使用die
并将其覆盖如下:
my $force;
BEGIN {
no warnings 'once';
Getopt::Long::Configure('pass_through');
GetOptions('force', \$force);
*CORE::GLOBAL::die = sub { warn @_ } if $force;
Getopt::Long::Configure('no_pass_through');
}
use My::Module;
...
die "maybe";
...
exit(1) if $force;
exit(0); # success!
我不喜欢这种方法,主要是因为有一些地方我仍然想死(例如缺少命令行参数)。我宁愿将die
的实例更改为warn
并执行条件use warnings FATAL => 'all'
1 。问题是use warnings
是词法范围的,所以这是无效的:
if (!$force) {
use warnings FATAL => 'all';
}
尝试使用postfix条件是语法错误:
use warnings FATAL => 'all' unless $force;
和use
不能在表达式中使用:
$force or use warnings FATAL => 'all'; # syntax error
我可以想到各种令人反感的解决方法(定义我自己的警告/死亡,在if / else中复制我的主要脚本代码等)但我正在寻求一种优雅的解决方案,有条件地应用use warnings
目前的词汇范围。 (在父范围中应用它也会起作用,但可能需要黑魔法。)
<小时/> 1:实际上,我想将
use warnings::register
添加到我的模块中,use warnings FATAL => 'My::Module'
添加到我的脚本中,但这个区别对于这个问题的目的并不重要。
答案 0 :(得分:4)
你可以尝试:
use if !$force, warnings => qw( FATAL all );
是的,有一个名为if
的模块与Perl一起分发,以便很容易进行条件导入。
请注意,这是在编译时进行评估的,因此需要在编译时定义$force
。 (可能在BEGIN { ... }
区块内。)根据您问题中的代码示例,您似乎已经考虑到了这一部分。
或者,更多手册:
BEGIN {
require warnings;
warnings->import(qw/ FATAL all /) unless $force;
}
完全不同的方法是使用信号处理程序$SIG{__WARN__}
或$SIG{__DIE__}
来判断是否在运行时死亡。