perl - 使用 REGEX_COND 时出现的错误

标签 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

这是一个已知的错误?如果是这样,它是在哪个版本中修复的?

最佳答案

这是您代码中的错误。
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';

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

关于perl - 使用 REGEX_COND 时出现的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47085824/

相关文章:

javascript - 从 perl 脚本获取查询时出现 XML 解析错误

mysql - Perl DBIx::Class 截断表

perl - 使用 AnyEvent::Handle 和 tcp_connect 重新连接

perl - 比较两个目录中常规文件的差异

perl - WWW::Mechanize::GZip 触发 __DIE__ 信号......为什么?

bash - 是否可以从 Perl 调用 bash 函数?

perl - 使用文件的内容作为程序的参数

perl - Perl 函数中的变量在函数外有意外的值

perl - 如何在不使用 Perl 格式的情况下格式化列?

perl - 使用 mod-perl 2 获取 http POST 请求的主体