归还正确的数量

Returning the Right Amount

你知道当你带着买错的东西回来时,你的另一半的表情吗?告诉你吧,我们会为此写一个脚本!

sub buy-eggs($amount --> Seq where *.elems == $amount) {
    my $forgotten-amount = (1..$amount).roll;
    return "egg" xx $amount - $forgotten-amount;
}

say buy-eggs 10;
Cannot do non-typename cases of type_constraint yet
at /home/dex/projects/blog/return-check.raku:3
------> $amount --> Seq where *.elems == $amount⏏) {

Raku 让我们失望了!但是,Raku 就是 Raku,我们可以帮助它。

multi sub trait_mod:<is>(Sub $s, :return-where(&condition)) {
    $s.wrap({
        my $ret = callsame;

        if !condition($ret) {
            fail ‚return condition does not match for sub ‘ ~ $s.name ~ ‚ for return value of ‘ ~ $ret.gist;
        }

        $ret
    });
}

现在我们可以检查一个 sub 是否返回一定数量的元素。

sub buy-eggs($amount --> Seq) is return-where(*.elems == 10) {...}

但有一个问题。与 where 子句不同,trait 不能访问签名作用域内的变量。我们可以使用 POST phaser 来处理。

sub buy-eggs($amount --> Seq) {
    my $forgotten-amount = (1..$amount).roll;
    return "egg" xx $amount - $forgotten-amount;

    POST { $_ == $amount or fail "back to the store!" }
}

在返回检查中加入适当的 where 子句,对于文档来说是很好的。如果我们能将任何输入和输出验证移到签名中,那么签名就变成了对输入和输出值的描述。而且与手写的文档完全相反,它与代码保持同步。

我希望配偶 agro 的前景能说服核心开发人员在返回检查中添加 where 子句。

by glfdex.

comments powered by Disqus