列表上下文中的匹配不会 return 空列表。为什么?

Matching in list context does not return empty list. Why?

from documentation

With or without parentheses, an empty list is returned upon failure.

但是我在失败时没有得到空列表:

my @l =  'a' !~ m/a/;
print scalar @l;       # 1
print defined $l[0];   # 1

use warnings;
print $l[0] eq '';     # 1

但是 =~ 我得到空列表:

my @l =  'a' =~ m/b/;
print scalar @l;       # 0

我不明白!~

This is perl 5, version 30, subversion 3 (v5.30.3) built for x86_64-linux

UPD

my $r =  { a => 'a', b => 'b', c => 'c' };
my $f =  { a => 'a', c => 'c' };

map{ $r->{ $_ } =~ $f->{ $_ } } %$f   or next; # If nothing is matched go to next record

map{ $r->{ $_ } !~ $f->{ $_ } } %$f   or next; # If all conditions meet, proceed

使用 !~ 绑定操作数不会导致匹配运算符简单地交换它在匹配时的 return 和不匹配时的 return 。

在列表上下文中,匹配运算符通常 returns 捕获的子字符串,如果没有匹配则为空列表。交换 return 值需要 return 在匹配项上创建一个空列表,并在没有匹配项时捕获子字符串。这是不可能的,因为当没有匹配时什么都不会被捕获。

s///tr/// 有类似的问题,因为它们通常 return 替换次数。

相反,EXPR !~ OP!( EXPR =~ OP ) 的缩写,! 在标量上下文中评估其操作数(因为它需要一个真值或假值)。


# Go to next record if nothing matches.
grep { $r->{ $_ } =~ $f->{ $_ } } keys(%$f)
   or next;

# Go to next record if everything matches.
# (Go to next record if nothing doesn't match.)
grep { $r->{ $_ } !~ $f->{ $_ } } keys(%$f)
   or next;

更清晰:

use List::Util qw( all none );

# Go to next record if nothing matches.
none { $r->{ $_ } =~ $f->{ $_ } } keys(%$f)
   or next;

# Go to next record if everything matches.
all { $r->{ $_ } =~ $f->{ $_ } } keys(%$f)
   and next;