如果REGEX_COND使用错误

时间:2017-11-02 22:48:47

标签: perl

如果程序名是以.t。

结尾的测试脚本,我想条件加载包

但是,当条件为正则表达式时,我遇到了use if失败的错误。我在Perl 5.10和5.16中对此进行了测试。

以下是以.t:

结尾的测试脚本
#!/usr/bin/env perl

use v5.10;

BEGIN { say "\$0 is '$0'" }

use if $0 =~ /\.t\z/, 'List::Util', ('pairmap');

say "List::Util is " . ( $INC{"List/Util.pm"} ? '' : 'NOT ' ) . 'included';

输出:

$ ./test.t
$0 is './test.t'
List::Util is included

但是,扩展名为.pl的同一文件失败:

$ ./test.pl
$0 is './test.pl'
Can't locate pairmap.pm in @INC (@INC contains: /usr/lib64/perl5/5.10.0 /usr/lib64/perl5 /usr/local/share/perl5/x86_64-linux-thread-multi /usr/local/share/perl5 /usr/local/lib64/perl5 /usr/share/perl5 /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/share/perl5/if.pm line 13.
BEGIN failed--compilation aborted at ./test.pl line 7.

如果我对正则表达式进行双重修改或将其更改为substr比较,我可以强制执行代码:

use if !!( $0 =~ /\.t\z/ ), 'List::Util', ('pairmap');
use if substr( $0, -2 ) eq '.t', 'List::Util', ('pairmap');

输出:

$ ./test.pl
$0 is './test.pl'
List::Util is NOT included

这是一个已知的错误吗?如果是这样,它修复了什么版本?

1 个答案:

答案 0 :(得分:8)

这是您的代码中的错误。

use MODULE之后的参数列表,列表上下文。

列表上下文中的

m//如果成功则返回捕获的字符串列表(如果正则表达式不包含捕获组,则返回1),或者失败时返回空列表。

因此:

use if "test.pl" =~ /\.t\z/, 'List::Util', ('pairmap');

相当于

use if (), 'List::Util', ('pairmap');

(匹配失败,因此返回一个空列表。)

列表上下文中的

,是列表连接运算符,因此这给出了:

use if 'List::Util', 'pairmap';

'List::Util'是一个真值,因此最终会加载pairmap.pm

use pairmap;

修复是给出匹配标量上下文:

use if scalar($0 =~ /\.t\z/), 'List::Util', 'pairmap';

!还为其操作数提供标量上下文,因此!!具有相同的效果。)