从Perl 6中的异常处理程序返回值 [英] Returning values from exception handlers in Perl 6

查看:48
本文介绍了从Perl 6中的异常处理程序返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试编写一个执行以下逻辑的Perl 6表达式:评估一个子表达式并返回其值,但是如果这样做会引发异常,请捕获该异常并返回一个固定值./p>

例如,假设我要除以两个数字,并且如果发生错误,则表达式的计算结果为 -1 .在Ruby中,我可能会这样写:

 商=开始;a/b;救援;-1;结尾 

在Emacs Lisp中,可能写为:

 (setq商(情况为nil(/a b)(错误-1)) 

我的第一次Perl 6尝试是这样的:

  sub may-throw($ a,$ b){如果$ b == 0,则死为零";$ a/$ b}我的$ quotient =做{may-throw($ a,$ b);CATCH {默认{-1}}}; 

但是这里 $ quotient 最终未定义,无论 $ b 是否为零.

似乎忽略了 CATCH 返回的值,或者至少在解决方案

catch块不起作用的原因是因为除以零本身并不是错误.Perl6将很高兴让您除以零并将该值存储为Rat.当您想以一种有用的方式(例如 say 它)显示所说的Rat时,就会出现此问题.到那时,您将收到一个返回的Failure,如果未处理,则返回Exception.

因此,您有一些选择.您可以在创建 $ q 之前检查 $ b :

  $ q = $ b == 0 ??-1 !!$ a/$ b; 

或者,如果您想保留实际值(请注意,可以对Rat的分子和分母进行内省而不引起被零除的错误),则当您使用 say 时,可以使用 .perl .Num 版本.

两者都为您提供 Rat 的十进制表示形式,其中 .perl 给出< 1/0> .Num 当分母为 0 时给出 Inf .

I've been trying to write a Perl 6 expression which performs the following logic: Evaluate a subexpression and return its value, but if doing so causes an exception to be raised, catch the exception and return a fixed value instead.

For example, suppose I want to divide two numbers and have the expression evaluate to -1 if an error occurs. In Ruby I might write:

quotient = begin; a / b; rescue; -1; end

In Emacs Lisp that might be written as:

(setq quotient (condition-case nil (/ a b) (error -1))

My first Perl 6 attempt was like so:

sub might-throw($a, $b) { die "Zero" if $b == 0; $a / $b }
my $quotient = do { might-throw($a, $b); CATCH { default { -1 } } };

But here $quotient ends up undefined, regardless of whether $b is zero.

It seems that that the value returned by CATCH is ignored, or at least on the doc page that describes how exceptions work, all of the CATCH bodies only do things with side effects, like logging.

That page mentions try as an alternative. I might write for example:

my $quotient = try { might-throw($a, $b) } // -1;

I find it a rather underwhelming solution. For one thing, the expression I'm evaluating might genuinely have an undefined value, and I can't distinguish this from the case where an exception was thrown. For another, I might want to fall back to different values depending on the class of the thrown exception, but try just swallows them all. I can put my own CATCH block in the try to distinguish among the exceptions, but then I'm back at the first case above, where the value from the CATCH is ignored.

Can Perl 6's exception handling do as I've expressed I want it to be able to do above?

EDIT:

The current answers are informative, but are focusing too narrowly on the semantics of the division operator. I've rewritten the question slightly to make the main issue of exception catching more central.

解决方案

The reason your catch block doesn't work is because dividing by zero isn't in and of itself an error. Perl6 will happily let you divide by zero and will store that value as a Rat. The issue arises when you want to display said Rat in a useful fashion (IE say it). That's when you get a Failure returned that becomes and Exception if not handled.

So you've a few options. You can check $b before you make $q :

$q = $b == 0 ?? -1 !! $a / $b; 

Or if you want to keep the real value (note you can introspect both the numerator and the denominator of a Rat without causing the divide by Zero error) when you say it you can use the .perl or .Num versions.

Both give you the decimal representation of the Rat with .perl giving <1/0> and .Num giving Inf when you have a 0 denominator.

这篇关于从Perl 6中的异常处理程序返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆