【问题标题】:Ruby Exception Handling QuestionsRuby 异常处理问题
【发布时间】:2009-04-30 01:02:56
【问题描述】:

我正在阅读 Programming Ruby 这本书,但在理解以下概念时遇到了问题:

  1. 作者讨论了代码中可能出现的“瞬时异常”,然后建议创建您自己的异常对象来处理它们。我不认为我完全理解什么是暂时性错误以及何时适合制作自己的 Exception 对象。他在Chapter 6 谈到定义异常时谈到了这一点:

例如,某些类型的网络错误可能是暂时的。第 6 章第 97 页。向异常添加信息。

  1. 我也很难在 ruby​​ 中使用 Catch and Throw。什么时候比提出和拯救更好?

【问题讨论】:

    标签: ruby exception-handling


    【解决方案1】:

    你能给我们一个关于“瞬态异常”行的页面引用吗?

    在任何情况下,您都可以随时创建一个新的异常,这样做通常是好的,这样您就可以传输有关该故障的更多信息。当您有低级别异常并希望将其变成对用户更有意义的东西时,这尤其有用。

    Ruby 中的 Throw/Catch 确实是一种非本地 goto,就像 C 中的 setjmp/longjmp,但表现更好。您可以随时使用它来转移执行很长的路要走。

    显然,出于同样的原因,您不想过多地使用goto,您也不想这样做。您可能会使用它的一个重要原因是在程序需要保持运行的情况下,因此如果您发现某些类型的错误,您可能会放弃您正在做的整个工作并重新开始。


    好的,这似乎不在我所拥有的任何一个版本的镐书的第 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"
    

    它现在向堆栈发送某种 RuntimeError 的东西,但现在附加了附加信息,即一个标志,上面写着“是的,这可以重试”。

    现在,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​​ 开发人员如何如此喜欢该语言的部分内容!
    猜你喜欢
    • 2016-06-27
    • 1970-01-01
    • 2011-01-18
    • 2011-04-27
    • 2011-11-02
    相关资源
    最近更新 更多