Ruby的救援替代方案?

时间:2010-04-17 05:19:59

标签: ruby exception exception-handling

似乎我的代码中到处都有begin ... rescue ... end个语句!这似乎不是正确的事情。

任何人都可以建议我如何捕捉任何异常,而不必将所有内容放在begin ... rescue ... end内?有什么方法可以告诉Ruby关闭并且即使引发异常也会继续运行吗?

4 个答案:

答案 0 :(得分:10)

与其他语言一样,对于任何非平凡的程序,您实际上需要一个经过深思熟虑的架构来处理异常。一种方法是在项目中定义异常处理范围,然后通常希望在范围边界捕获(救援)异常。有一个权衡。您在堆栈中距离发生异常的位置越近,您获得的有关触发它的条件的上下文信息就越多。如果您尝试过于细化,则会遇到您所描述的问题。另一方面,如果您只捕获堆栈顶部的异常(在“main”中),则没有上下文。因此,定义异常处理范围涉及评估与特定程序或系统相关的权衡。

Ruby使我们能够“重试” - 在其他一些语言中不可用。这应该谨慎使用!但是在有意义的地方(例如,等待网络或资源被释放),这些异常需要在本地处理。

否则,我倾向于在大型项目上以相当粗粒度的级别定义异常范围。捕获一些上下文信息通常很有用,因为异常从起始点到各种异常范围边界起泡。为了解决这个问题,您可以通过定义一些特定于应用程序的异常类型来扩展Ruby异常类层次结构,但同样需要权衡。您的项目应该有明确的标准,关于何时使用自定义异常类型与捕获消息字段中的上下文数据,消息字段应包含哪些类型的信息等,以及用于编目代码可以生成的消息的策略。

在大多数情况下,可以允许异常向上传播到集中处理程序,记录(对于技术团队和支持),为用户生成有用的错误消息,并确定条件是否严重到足以要求你的程序退出。通常,所有异常都应在您的代码内或您正在使用的应用程序框架内处理。不应允许任何异常转义为语言运行库或操作系统的默认异常处理。

这些是我的想法主要基于其他语言的经验,但我认为它们非常适用。总而言之,在一个大型项目中,您需要花费大量精力来设计异常处理,而不是临时方法。

答案 1 :(得分:6)

def action
    yield
    rescue
        ....
    ensure
        ....
end

action { stuff_goes_here }

答案 2 :(得分:4)

可以让它看起来更清洁的一件事就是在方法结束时进行救援,这样你就不需要开始和另一个级别的缩进:

def get_file_prompt
  print "Enter file name: "
  return File.open(read)
rescue StandardError
  puts "File could not be opened"
  return nil
end

答案 3 :(得分:1)

嗯,不。例外的全部意义在于它们是必须处理的条件。

以这种方式思考:例外是你的朋友!没有它们你就必须写出许多难以阅读和维护的无聊条件陈述。

如果您正在学习Ruby(或任何具有异常系统的语言),处理异常是最重要的方面之一,您最好花时间弄清楚如何处理它们,何时重新开始提高它们,当它们被忽视时是安全的。

相关问题