使用" Learning Perl"的第15章中给出的给定时间语句的示例书不能正常工作。 我使用的是Perl v5.22.1。我尝试重现以下代码(参见"学习Perl"第五版,第227页。):
use 5.010;
given ($ARGV[0])
{
when(/fred/i) {say "Name has fred in it"; continue}
when(/^Fred/) {say "Name starts with Fred"; continue}
when('Fred') {say "Name is Fred";}
default {say "I don't see a Fred"}
}
当我运行脚本时,我得到以下结果:
D:\>Perl D:\Perl\Example113.pl Frederick
given is experimental at D:\Perl\Example113.pl line 5.
when is experimental at D:\Perl\Example113.pl line 7.
when is experimental at D:\Perl\Example113.pl line 8.
when is experimental at D:\Perl\Example113.pl line 9.
Name has fred in it
Name starts with Fred
I don't see a Fred
正如您所看到的,默认块的工作方式与预期相反。 同时,如果你交换了第一个和最后一个块'当'时,它的工作方式几乎与书中描述的一样:
use 5.010;
given ($ARGV[0])
{
when('Fred') {say "Name is Fred"; continue}
when(/^Fred/) {say "Name starts with Fred"; continue}
when(/fred/i) {say "Name has fred in it"; }
default {say "I don't see a Fred"}
}
是什么给了我们下一个输出:
D:\>Perl D:\Perl\Example113.pl Frederick
given is experimental at D:\Perl\Example113.pl line 5.
when is experimental at D:\Perl\Example113.pl line 7.
when is experimental at D:\Perl\Example113.pl line 8.
when is experimental at D:\Perl\Example113.pl line 9.
Name starts with Fred
Name has fred in it
我做错了什么或在书中是不正确的例子?
答案 0 :(得分:5)
首先,虽然探索和游戏很好,但我必须重复perlsyn says
如前所述,“切换”功能被认为是高度的 实验;它很快就会发生变化。
如果这还不够,可以稍早一点in perlsyn
when
的 EXPR 参数确实很难描述 确切地说,但总的来说,它试图猜测你想要做什么。有时 它被解释为$_ ~~ EXPR
,有时却没有。它也是 当被given
块词汇包围时,它的行为会有所不同 由foreach
循环动态包含时。规则也很远 这里难以理解。稍后请参阅Experimental Details on given and when。
我不知道如何看待“很难准确描述”的功能。另请注意“大部分功能来自隐式智能匹配”(同一页面)。重要的是,这个将改变,而且非常可能显着。
清除之后,您展示的行为是预期的。来自example in perlsyn
given ($foo) { when (undef) { say '$foo is undefined'; } when ("foo") { say '$foo is the string "foo"'; } ... }
其中$foo
等于字符串"foo"
,不匹配;这不是正则表达式匹配,而是字符串相等。
在您的示例中,字符串 'Fred'
与Frederick
不相等。在第二个中有continue
,所以它确实进入下一个分支,但在第一个分支中没有(虽然它也是default
之前的最后一个分支)。使用输入Fred
运行程序以查看。
答案 1 :(得分:1)
如果不continue
,when
和default
退出周围的given
或移至周围for
的下一个项目。
使用continue
,执行下一个语句。
到达时无条件执行default
块。
例如,
given ($ARGV[0]) {
say "Checking for 'x'";
when (/x/) { say 'contains an x'; continue; }
say "Checking for 'y'";
when (/y/) { say 'contains a y'; }
default { say 'does not contain a y'; }
}
y
:
Checking for 'x'
Checking for 'y'
contains a y
x
:
Checking for 'x'
contains an x
Checking for 'y'
does not contain a y
xy
:
Checking for 'x'
contains an x
Checking for 'y'
contains a y