perl 使用什么代替Smartmatch?

neskvpey  于 2023-03-13  发布在  Perl
关注(0)|答案(4)|浏览(161)

我刚刚升级到Perl 5.26.1,现在我得到了

Smartmatch is experimental at check_tr.pl line 67.

其中所讨论的代码是

my @patterns = (qr/summary:\s+(.+?) in\s+(.+?) - average of\s+(.+?)$/,
        qr/summary:\s+(.+?) in\s+(.+) (.+? .+?)$/);
my $r = "";
opendir(DIR, $dir) or die $!;
while(my $file = readdir(DIR)) {

    next if ($file =~ m/^\./);
     open(F, '<', "$dir/$file") or die $!;

     if (<F> ~~ @patterns) {
         $r .= <F>;
...

问题

理想情况下,尽可能少地更改代码。我应该做什么来代替智能匹配?

flmtquvp

flmtquvp1#

只要拼写出你的意思。例如,如果你想检查标题行是否匹配@patterns中的任何正则表达式:

use List::Util 'any';
...
my $line = <F>;
if (any { $line =~ $_ } @patterns) { ... }

尽管在这种情况下,预编译单个模式可能更明智,例如:

my ($pattern) = map qr/$_/, join '|', @patterns;
...
if (<F> =~ $pattern) { ... }

如果您的@patterns数组包含不同种类的数据,您可能需要选择不同的匹配运算符,例如==eq。如果@patterns不是相同的“类型”,并且您确实需要smartmatch行为,您可以将警告静音并继续使用它:

use experimental 'smartmatch';

但是,这可能会在将来没有进一步警告的情况下中断。

wljmcqd8

wljmcqd82#

Smartmatch处于实验阶段的原因是,如果不引用文档,很难弄清楚它会做什么。即使如此,我们如何解释上面的代码呢?
这是否属于以下情况:

ARRAY1    ARRAY2     recurse on paired elements of ARRAY1 and ARRAY2[2]
            like: (ARRAY1[0] ~~ ARRAY2[0])
                    && (ARRAY1[1] ~~ ARRAY2[1]) && ...

我们假设<F>在列表上下文中解释,并在单个调用中清空?
或者这是一种情况:

Any       ARRAY      smartmatch each ARRAY element[3]
            like: grep { Any ~~ $_ } ARRAY

我猜是第二种,在这种情况下,上面的文档片段给了你一个很好的(更清晰的)编码选择,假设@patterns包含正则表达式,你也可以用=~替换~~
如果你不喜欢文档中的grep选项,我建议你研究一下List::UtilList::MoreUtils,两者都包含一个any调用,它可以作为grep的短路。或者,如果你试图实现ARRAY1 ARRAY2选项,后面的库包含一个pairwise调用。

pbgvytdp

pbgvytdp3#

必须同意其他答案,Perl的 smartmatch 最好避免。
在Perl-Monks站点上有一个替代方法列表(带有示例):
PerlMonks - Smartmatch alternatives

dgtucam1

dgtucam14#

如果您有几种数据要比较,并且不想在代码中使用一长串if / elsif来检查所有可能的情况,那么TOBYINK的match::simple模块是旧的smartmatch的一个很好的替代品。

相关问题