在"编程Perl"一书中有一个片段(剪切):
默认情况下,当(EXPR)被视为
$_;
(即$_ ~~ EXPR
)的隐式智能匹配时。然而,如果对when的EXPR自变量是下面列出的10种例外形式之一,它被直接评估为布尔结果,并且没有发生智能匹配:
。。。
正则表达式匹配形式为/REGEX/、$foo=~/REGEX/或$foo=~经验。
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
我不明白这里发生了什么,有人能这么乐意帮忙吗?
提前感谢。
仔细阅读文档:
另一个有用的快捷方式是,如果将文字数组或哈希用作"给定"的自变量,它就变成了一个引用。所以例如,"giving(@foo)"与"given(\\foo))"相同。
因此,given (@a)
变为given(@a)
。没有智能匹配,因为您使用when (/a/)
,所以您正在尝试匹配
@a =~ /a/
引用已字符串化。它有时包含"a",如ARRAY(0x9a4e7f8)
,但通常不包含:-)
documentatiom意味着when (/a/)
不等价于if ($_ ~~ /a/)
,后者将检查任何数组元素是否与正则表达式匹配,而等价于if ($_ =~ /a/)
,后者只是检查标量$_
是否匹配。
将数组传递给given
时,它会为该数组分配引用。因为(正如文档所说)没有使用智能匹配运算符,所以像when (/a/)
这样的条件等价于@a =~ /a/
。
因为在尝试正则表达式匹配之前,引用将被字符串化,所以它将比较类似ARRAY(0x61c6dc)
的内容。由于您正在字符串中查找小写的a
,因此如果字符串中的十六进制数组位置恰好包含a
,则情况会如此。根本不是你想要的!
when(/a/)
确实做了一些类似if (/a/)
的事情,而不是像if ($_ ~~ /a/)
。如果您想要后者,则应该使用when (qr/a/)
。
when ('a')
when (123)
是的缩写
when ($_ ~~ 'a')
when ($_ ~~ 123)
这份名单是这种行为的例外。你特别询问的是
when (/b/)
when ($x =~ /c/)
不是的缩写
when ($_ ~~ /b/)
when ($_ ~~ $x =~ /c/)
它们具有正常意义(when
之外),即
when ($_ =~ /b/)
when ($x =~ /c/)