Wait the light to fall

自定义 when

焉知非鱼

Custom When

我不太喜欢上一篇文章中使用匹配的语法。它的参数列表中的逗号看起来很奇怪,不合适。也许是因为我的眼睛习惯了给定的块。睡一觉就好了。

sub accord(&c) { (c(CALLER::<$_>); succeed) if &c.cando(\(CALLER::<$_>)) }

given Err.new(:msg<a>) {
    accord -> Hold (:$key) { putholding $key; }
    accord -> Err (:$msg) { warnERR: $msg}
    default { failunsupported}
}

这是因为 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) { putholding $key; }
        accord -> Err (:$msg) { warnERR: $msg}
        default { warnunsopported}
    }
}

原文链接: https://gfldex.wordpress.com/2021/02/25/custom-when/