3

在“Programming Perl”一书中有一个片段(删减):

默认情况下,when(EXPR) 被视为隐式智能匹配,$_;$_ ~~ EXPR. 但是,如果 when 的 EXPR 参数是下面列出的 10 种异常形式之一,则直接评估它以获得布尔结果,并且不会发生智能匹配:

  1. ...

  2. /REGEX/、$foo =~ /REGEX/ 或 $foo =~ EXPR 形式的正则表达式匹配。

这是什么意思evaluated directly for a Boolean result

例子:

#!/usr/bin/perl
use v5.14;
my @a = ('aaa', 'bbb', 'ccc');

given(@a) {
    when (/a/) { say '@a contains an a'; }
    default    { say '@a does not contain an a' }
}

当我运行它时,输出会不时变化:

@a does not contain an a

@a contains an a

@a does not contain an a

@a does not contain an a

我不明白这里发生了什么,有人能这么乐于助人吗?

提前欣赏。

4

4 回答 4

11

仔细阅读文档:

另一个有用的快捷方式是,如果您使用文字数组或散列作为“给定”的参数,它就会变成引用。例如,“given(@foo)”与“given(\@foo)”是一样的。

因此,given (@a)变成given(\@a)。没有智能匹配,因为你使用when (/a/),所以你正在尝试匹配

\@a =~ /a/

引用是字符串化的。它有时包含“a”,如ARRAY(0x9a4e7f8),但通常不包含 :-)

于 2012-07-27T12:20:56.667 回答
5

文档意味着 thatwhen (/a/)不等同于if ($_ ~~ /a/),它将检查是否有任何数组元素与正则表达式匹配,而是 to if ($_ =~ /a/),它仅检查标量是否$_匹配。

当您将数组传递给given它时,它会分配对该数组的引用。并且因为(如文档所述)未使用智能匹配运算符,因此类似的条件when (/a/)相当于\@a =~ /a/.

因为在尝试正则表达式匹配之前引用将被字符串化,所以它将比较类似ARRAY(0x61c6dc). 由于您正在寻找字符串中的小写字母a,因此如果字符串中的十六进制数组位置恰好包含a. 根本不是你想要的!

于 2012-07-27T12:31:19.960 回答
4

when(/a/)真的很喜欢if (/a/),不喜欢if ($_ ~~ /a/)。如果你想要后者,你应该使用它when (qr/a/)

于 2012-07-27T13:50:29.273 回答
4
when ('a')
when (123)

简称

when ($_ ~~ 'a')
when ($_ ~~ 123)

该列表是该行为的例外。你特别问的那个意味着

when (/b/)
when ($x =~ /c/)

不是缩写

when ($_ ~~ /b/)
when ($_ ~~ $x =~ /c/)

它们有其正常(在 之外when)的含义,即

when ($_ =~ /b/)
when ($x =~ /c/)
于 2012-07-27T14:59:00.693 回答