经过一番反反复复,我找到了一个实用的方法来处理 Shell::Piping 中的错误条件。这个实用的方法是有多个方法。一个进程确实有一个 exitinteger(称为代码,因为它可能很神秘)和文本输出到 STDERR 来表示出了问题。有时我们需要粗心的错误处理,有时我们需要研究文本输出并对其做出反应。
我发现了一个非常好的方法,使用 Junction 和 Raku 的类型系统来从错误处理中去除一些模板。将两者结合起来,我们可以创建一个灵活的类型。
class Exitcode {
has $.value;
has $.command;
method Numeric { $.value }
method Str { $.command }
}
所以这个类产生的对象既是一个数字又是一个文本。实际看的是什么,要看是谁在看。我们可以使用 infix:<~~>
来决定使用哪个比较运算符。
say $ex ~~ 42 && $ex ~~ ‚find‘; # OUTPUT: True
这还是挺啰嗦的。我们可以用 Juncttion,因为它结合得比 ~~
较紧。
say $ex ~~ 42 & ‚find‘; # OUTPUT: True
现在,我们可以 CATCH
一个异常,并缩小管道中的命令,很容易失败。
CATCH {
when X::Shell::NonZeroExitcode {
given .exitcode {
when 42 & ‚find‘ {
warn ‚Oh now! We found the answer!‘;
}
}
}
}
并不是所有模块的用户都可能喜欢使用 Exception
。所以我们在 Shell::Pipe 对象中使用一个构造来创建一个 Failure 从 .sink
返回。如果调用了 Shell::Pipe.exitcode
方法,我们就会认为用户是在用手处理它们。然后,我们可以调用 .handled
来"中止"这个 Exception
。这一点必须简单,否则可能会被跳过。因此,在 Exitcode
这个类中,强转器方法的使用很不寻常。