Raku中try块最后一条语句为run时异常未捕获问题
关于Raku中try块内run作为最后语句时CATCH无法捕获异常的问题
问题现象
在Raku中,当try块的最后一条语句为run时,run抛出的异常无法被块内的CATCH捕获;若run不是最后一条语句,异常可正常捕获。将CATCH块移至run语句之后,问题可解决,但疑问在于:按预期CATCH块应能捕获其作用域内任意位置抛出的异常,位置不应影响捕获逻辑。
代码示例与结果
1. run作为最后语句(异常未被捕获)
try { CATCH { default { say 'CAUGHT!'; } } run 'lss', '-al'; }
执行输出:
$ raku try-run-bug.raku The spawned command 'lss' exited unsuccessfully (exit code: -1, signal: 254) (OS error = Failed to spawn process lss: no such file or directory (error code -2)) in block <unit> at try-run-bug.raku line 1
2. run后添加其他语句(异常被捕获)
try { CATCH { default { say 'CAUGHT!'; } } run 'lss', '-al'; say 'foo'; }
执行输出:
$ raku try-run-bug-workaround.raku CAUGHT!
3. 修正:将CATCH移至run之后(异常被捕获)
try { run 'lss', '-al'; CATCH { default { say 'CAUGHT!'; } } }
执行输出:
$ raku try-run-bug-fixed.raku CAUGHT!
测试环境
$ raku -v Welcome to Rakudo™ v2024.09. Implementing the Raku® Programming Language v6.d. Built on MoarVM version 2024.09.
环境通过rakubrew搭建。
分析与结论
此行为疑似Rakudo的实现Bug。根据Raku语言规范,CATCH块属于词法作用域,应能捕获其所在作用域内所有位置抛出的异常,与块内位置无关。
临时解决方案:
- 将
CATCH块移至try块的末尾 - 在
run语句后添加任意语句(如Nil;)以避免其成为最后一条语句
内容的提问来源于stack exchange,提问作者JustThisGuy
相关产品推荐
相关产品推荐

