我希望根据用户的偏好,致命错误可以降级为警告(或者相反,警告可以升级为致命错误)。目前,我正在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!
Run Code Online (Sandbox Code Playgroud)
我不喜欢这种方法,主要是因为有几个地方我仍然想死(例如缺少命令行参数)。我宁愿更改(大多数)实例die
towarn
并执行条件use warnings FATAL => 'all'
1。问题是它use warnings
是词法范围的,所以这是无效的:
if (!$force) {
use warnings FATAL => 'all';
}
Run Code Online (Sandbox Code Playgroud)
尝试使用后缀条件是一个语法错误:
use warnings FATAL => 'all' unless $force;
Run Code Online (Sandbox Code Playgroud)
并且use
不能在表达式中使用:
$force or use warnings FATAL => 'all'; # syntax error
Run Code Online (Sandbox Code Playgroud)
我可以想到各种令人讨厌的解决方法(定义我自己的 warn/die、在 if/else 中复制我的主脚本代码等),但我正在寻求一种有条件地应用于use warnings
当前词法范围的优雅解决方案。(将其应用于父范围也可以,但可能需要黑魔法。)
use warnings::register
到我的模块和use warnings FATAL => 'My::Module'
脚本中,但对于这个问题的目的来说,区别并不重要。
你可以尝试:
use if !$force, warnings => qw( FATAL all );
Run Code Online (Sandbox Code Playgroud)
是的,有一个名为 的模块if
随 Perl 一起分发,使条件导入变得非常容易。
请注意,这是在编译时评估的,因此$force
需要在编译时定义。(可能在一个BEGIN { ... }
块内。)根据您问题中的代码示例,您似乎已经弄清楚了该部分。
或者,更多手动:
BEGIN {
require warnings;
warnings->import(qw/ FATAL all /) unless $force;
}
Run Code Online (Sandbox Code Playgroud)
一种完全不同的方法是使用信号处理程序$SIG{__WARN__}
或$SIG{__DIE__}
在运行时决定是否死亡。
归档时间: |
|
查看次数: |
251 次 |
最近记录: |