这对我来说似乎很疯狂:
use v6.d;
say "Before division by zero!";
my $result = divide(3, 0);
say "After division by zero!";
sub divide($a, $b) {
my $result;
$result = $a / $b; # Line 11
return $result;
}
sub go($x) {
say "hello";
say $x; # Line 17
}
go($result); # Line 20
--output:--
Before division by zero!
After division by zero!
hello
Attempt to divide by zero when coercing Rational to Str
in sub go at b.raku line 17
in block <unit> at b.raku line 20
Run Code Online (Sandbox Code Playgroud)
错误提示查看第 17 行。然而,错误来自第 11 行。
在 Perl 中:
use strict;
use warnings;
use feature qw{say};
use Data::Dumper;
say "Before division by zero!";
my $result = divide(3, 0);
say "After division by zero!";
sub divide {
my ($a, $b) = @_;
my $result = $a / $b; # Line 13
return $result;
}
sub go {
my ($x) = @_;
say "hello";
say $x;
}
go(20, 30);
--output:--
Before division by zero!
Illegal division by zero at a.pl line 13.
Run Code Online (Sandbox Code Playgroud)
perl 程序产生一个错误,该错误指向实际导致该错误的代码。
此外,在 raku 中,你甚至不能使用 try 块来包含错误:
sub divide($a, $b) {
my $result;
try {
$result = $a / $b;
}
return $result;
}
Run Code Online (Sandbox Code Playgroud)
这会产生与上面的 raku 程序相同的输出。
raku 为何做出这样的决定:
处理异常时,异常被“使用”的地方决定了它何时被抛出。
...其中“used”似乎意味着用 say() 输出?正如您从我的示例中看到的,很难找出代码中的错误所在。这与惰性评估有关吗?
这个问题重申了流行的“ Raku by Example ”课程中的这个例子。该课程是这样解释这种情况的:
最后两个代码片段说明了 Raku 允许的软失败机制。简而言之,这意味着在即将使用与异常相关的值之前不会引发异常。这就是这些代码片段中发生的情况;仅当使用 div(3,0) 中的值时才会引发异常。
该参考文献未准确提供或在上下文中提供。
问题的最后一部分询问这个陈述“为什么 Raku 决定这样做”......但原始参考文献已经回答了这个问题。