Whereceptions

楽土

我有一个 sub,它接收一个文件,并试图防范自己遇到不存在的文件。where 子句没有做好错误信息。

sub run-test(IO() $file where .e & .f) { };
run-test('not-there.txt');
# OUTPUT:
# Constraint type check failed in binding to parameter '$file'; expected anonymous constraint to be met but got IO::Path (IO::Path.new("not-th...)

那个子例程的签名很有表现力。我们常常没有时间去阅读代码,去追寻错误。这就是为什么坏的错误信息是 LTA。我们可以用 diefail 来扩展任何 where 子句,以提供一个更好的信息。

sub run-test(IO() $file where .e && .f || fail("file $_ not found")) { };
run-test('not-there.txt');
# OUTPUT:
# file not-there.txt not found

我们还可以抛出异常的原因。只用一个参数,签名已经变得相当长了。另外,在处理很多文件时,我们会反复写同样的代码。由于我们不使用 Java 编码,所以我们宁愿不这样做。

my &it-is-a-file = -> IO() $_ {
    .e && .f || fail (X::IO::FileNotFound.new(:path(.Str)))
}
sub run-test(IO::Path $file where &it-is-a-file) { }

这样就好多了。由于异常是类,我们可以在它们之间重用代码。比如彩色输出和检查坏掉的符号链接。

class X::Whereception is Exception is export {
    has $.stale-symlink is rw;
    method is-dangling-symlink {
        $.stale-symlink = do with $.path { .IO.l & !.IO.e };
    }
}

class X::IO::FileNotFound is X::Whereception is export {
    has $.path;
    method message {
        RED $.is-dangling-symlink ?? „The file ⟨$.path⟩ is a dangling symlink.“ !! „The file ⟨$.path⟩ was not found.“
    }
}

我已经在 Shell::Piping 中添加了一些。非常欢迎大家提出建议,还有什么需要检查的。

原文链接: https://gfldex.wordpress.com/2020/08/09/whereceptions/

comments powered by Disqus