自定义 when
— 焉知非鱼Custom When
我不太喜欢上一篇文章中使用匹配的语法。它的参数列表中的逗号看起来很奇怪,不合适。也许是因为我的眼睛习惯了给定的块。睡一觉就好了。
sub accord(&c) { (c(CALLER::<$_>); succeed) if &c.cando(\(CALLER::<$_>)) }
given Err.new(:msg<a>) {
accord -> Hold (:$key) { put „holding $key“; }
accord -> Err (:$msg) { warn „ERR: $msg“ }
default { fail ‚unsupported‘ }
}
这是因为 accord
模仿了 when
的工作。它做了一些匹配,当 True 时调用一个块,并在每个块的结尾添加一个 success(通过抛出一个控制异常)。given 所做的只是设置主题。它还充当了 caller 的角色,所以我们可以通过一个伪包来访问它的 $_
。利用 pointy 的签名来做解构是相当强大的。把这个添加到 CORE 中可能是个好主意。
我们可能要把 Raku 的定义改成: “Raku 是一种高度可组合的编程语言”, 在这里,所有的东西都会落到实处。"
更新一下。
有些情况下,$_
不是动态的。另外,success 正在抛出一个控制异常,而这些的处理程序是由 when 或默认添加的。这种情况是在编译时发生的,目前不能用宏来解决。第一个问题可以用黑魔法解决。后一个问题需要用默认块。我没有找到一种方法来提供一个合理的错误信息,如果缺少这个块。
multi sub accord(&c) {
use nqp;
$_ := nqp::getlexcaller('$_');
(c($_); succeed) if &c.cando(\($_))
}
for @possibilities.roll(1) -> $needle {
given $needle {
accord -> Hold (:$key) { put „holding $key“; }
accord -> Err (:$msg) { warn „ERR: $msg“ }
default { warn ‚unsopported‘ }
}
}