Ruby异常处理问题

3
我正在阅读《Programming Ruby》一书,但是我无法理解以下概念:
1. 作者谈到可能会在代码中出现“瞬态异常”,然后建议创建自己的异常对象来处理它们。我不认为我完全理解什么是瞬态错误,什么时候适合创建自己的异常对象。他在第6章中讨论了这个问题,当他谈到定义异常时:
例如,某些类型的网络错误可能是瞬态的。第6章。第97页。将信息添加到异常中。 2. 我也很难理解在Ruby中使用Catch和Throw的用法。什么情况下使用它比raise和rescue更好?
1个回答

11

你能告诉我们“瞬态异常”一行的页面参考吗?

无论如何,您随时可以创建新的异常,并且通常最好这样做,以便您可以传输有关故障的更多信息。当您拥有低级异常并希望将其转换为对用户更有意义的内容时,特别适用。

Ruby中的Throw/Catch实际上是一种非本地goto,类似于C中的setjmp/longjmp,但表现更好。每当您想要传输长距离的执行时就会使用它。

显然,出于同样的原因,您不想经常使用 goto ,也不想这样做。您可能使用它的一个重要原因是程序需要保持运行状态,因此,如果捕获某些类型的错误,则可能会放弃正在进行的整个工作并返回到起点。


好的,在我手头的pickaxe书籍的任一版本的第97页似乎没有这个内容,但我理解了什么意思。哦,在这里,第三版的第157页。

首先,在“瞬态”问题方面,可能会出现一些网络问题,然后解决自己,例如当BOFH拔掉网络电缆并重新插入时。因此,在某些情况下,您可能想要等待几秒钟以让其稳定下来,然后再尝试,而不是惊慌失措。你怎样做呢?

在这种情况下,他们让您定义新的异常类型。这只需使用继承即可完成:

class RetryException < RuntimeError
  # so this is a kind of RuntimeError which is a kind of Exception
  attr: ok_to_retry
  def initialize(ok_to_retry)
     @ok_to_retry
  end
end

如果出现问题,您可以引发这些新的可重试异常之一。

raise RetryException.new(true), "transient read error"

现在,它会向上抛出一种类似于运行时错误的东西,但现在附加了额外的信息,即一个标志,表示“是的,这可以重试。”

现在,在Ruby中有一件非常棒的事情:它具有内置的重试某些操作的能力。因此,在堆栈的某个地方,您有以下代码:

begin
   # do something that raises this exception
   do_something()
rescue RetryException => detail 
   # if the exception is one of these retryable ones, 
   # catch it here, but it in detail
   if detail.ok_to_retry  
      retry
   end
   # this means exactly the same as 'retry if detail.ok_to_retry`
   # from the book, btw

   # if it STILL doesn't work, send the exception on
   raise # just re-raises the last exception
end

现在你可以看到 Ruby 开发者为什么会深爱这门语言的部分原因! - animal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接