given-when 有两个小的改变, 并且这俩改变都是开启新行为的, 而不是限制已存在的行为。
第一个小的改变: when 的开关行为不仅仅是用于 given 块儿中的, 而是可以用在任何”主题化”的块儿中的, 例如 for 循环中或接收 $_
作为参数的子例程中。
given $answer {
when "Atlantis" { say "那是对的" }
default { say "BZZZZZZZZZZZZZ!" }
}
for 1..100 {
when * %% 15 { say "Fizzbuzz" }
when * %% 3 { say "Fizz" }
when * %% 5 { say "Buzz" }
default { say $_ }
}
sub expand($_) {
when "R" { say "红警" }
when "G" { say "绿警" }
when "B" { say "蓝警" }
default { say $_ }
}
但是甚至不接受 $_
作为参数的子例程也得到了它们自己的词法变量 $_
供修改。所以规则就是”现在, 在 $_ 中有某些我能启动的好东西吗”。如果我们想要, 我们甚至能自己设置 $_
。
sub seek-the-answer() {
$_ = (^100).pick;
when 42 { say "The answer" }
default { say "A number" }
}
换句话说, 我们已经知道了 when 和 given 是单独的。Switch 语句逻辑都在 when 语句中。
第二个小改变: 你可以嵌套 when 语句!
我很确信你没有在野外见过这种用法。但它有时候特别有用:
when * > 2 {
when 4 { say 'Four!' }
default { say 'huge' }
}
default {
say 'little'
}
你可能记得, 在 when 块儿中有一个隐式的 succeed 语句在末尾, 这让周围的主题化块退出。(意思是你不必记着手动退出 switch 语句)。 如果你想重写 succeed 语句并继续通过 when block, 那么你在 when block 的末尾写上一个显式的 proceed 即可。
given $verse-number {
when * >= 12 { say "Twelve drummers drumming"; proceed }
when * >= 11 { say "Eleven pipers piping"; proceed }
# ...
when * >= 5 { say "FIIIIIIVE GOLDEN RINGS!"; proceed }
when * >= 4 { say "Four calling birds"; proceed }
when * >= 3 { say "Three French hens"; proceed }
when * >= 2 {
say "Two turtle doves";
say "and a partridge in a pear tree";
}
say "a partridge in a pear tree";
}
given 和 when 是正交的, 意味着你可以单独使用 given、单独使用 when、given/when 同时使用。
given 42 { .say; .Numeric; } # 42
这比下面这个等价的表达式更易读:
{ .say; .Numeric; }(42) # 42
given 作为语句
given
可以跟着一个语句以在它跟着的语句中设置主题(topic)。
.say given "foo";
# OUTPUT
# «foo
»
printf "%s %02i.%02i.%i",
<Mo Tu We Th Fr Sa Su>[.day-of-week - 1],
.day,
.month,
.year
given DateTime.now;
# OUTPUT«Sa 03.06.2016»