为什么在Ruby中“拯救异常=>e”是不好的风格?

为什么在Ruby中“拯救异常=>e”是不好的风格?

赖安·戴维斯Ruby QuickRef说(没有解释):

不要拯救例外。永远不会。不然我就捅你。

为什么不行?该怎么做才是对的?


哈士奇WWW
浏览 877回答 3
3回答

萧十郎

使用StandardError而不是一般的异常捕获。当重新引发原始异常时(例如,当救援只记录异常时),Exception可能没问题。Exception是Ruby异常层次结构所以当你rescue Exception你从一切,包括子类,如SyntaxError, LoadError,和Interrupt.援救Interrupt防止用户使用克特C退出程序。援救SignalException阻止程序正确响应信号。它将是无法杀死的,除非.kill -9.援救SyntaxError意味着eval失败的人会默默地这样做。所有这些都可以通过运行这个程序来显示,并试图克特C或kill它:loop do   begin     sleep 1     eval "djsakru3924r9eiuorwju3498 += 5u84fior8u8t4ruyf8ihiure"   rescue Exception     puts "I refuse to fail or be stopped!"   endend救出Exception甚至不是默认的。做begin   # iceberg!rescue   # lifeboatsend救不出Exception,它拯救了StandardError..您通常应该指定一些比默认值更具体的内容。StandardError,但是从Exception 变宽范围而不是缩小它,可能会有灾难性的结果,并使找虫极其困难.如果你遇到了什么情况,你真的想从StandardError如果您需要一个变量(除了这个例外),您可以使用以下形式:begin   # iceberg!rescue => e  # lifeboatsend相当于:begin   # iceberg!rescue StandardError => e  # lifeboatsend这是少数几个正常的案例之一Exception用于日志记录/报告,在这种情况下,您应该立即重新引发异常:begin   # iceberg?rescue Exception => e  # do some logging   raise e  # not enough lifeboats ;)end

小唯快跑啊

假设你在一辆车里(运行Ruby)。您最近安装了一个带有空中升级系统的新方向盘(该系统使用eval),但是您不知道有一个程序员在语法上搞砸了。你在一座桥上,意识到你正向栏杆走一点,所以你向左拐。def turn_left  self.turn left:end哎呀!那可能是不好™,幸运的是,Ruby引发了一个SyntaxError.车应该马上停下来-对吗?没有。begin   #...   eval self.steering_wheel  #...rescue Exception => e  self.beep  self.log "Caught #{e}.", :   warn  self.log "Logged Error - Continuing Process.", :infoend哔声警告:已捕获SyntaxError异常。信息:记录错误-继续处理。你注意到有什么地方不对劲,你就在紧急情况下摔了一跤(^C: Interrupt)哔声警告:捕获中断异常。信息:记录错误-继续处理。是啊-没什么用。你离铁轨很近,所以把车停在公园里kill英灵:SignalException).哔声警告:捕获SignalException异常。信息:记录错误-继续处理。最后一秒钟,你拿出钥匙(kill -9),汽车停了下来,你猛地冲进方向盘(安全气囊无法充气,因为你没有优雅地停止程序-你终止了程序),而你车后部的电脑猛地撞到了它前面的座位上。一罐半罐可乐洒在报纸上。后面的杂货都被压碎了,而且大部分都是蛋黄和牛奶。这辆车需要认真的修理和清洗。(数据损失)希望你有保险(备份)。哦,是的-因为气囊没有充气,你可能受伤了(被解雇,等等)。但是等等!有更多您可能想要使用的原因rescue Exception => e!假设你是那辆车,你想确保安全气囊膨胀,如果汽车超过了它的安全停车动量。 begin      # do driving stuff  rescue Exception => e    self.airbags.inflate if self.exceeding_safe_stopping_momentum?     raise end这里是规则的例外:你可以抓住Exception 只有当你重新引发异常的时候..所以,一个更好的规则就是不要吞下Exception,并且总是重提错误。但是,在Ruby这样的语言中,添加援救是很容易忘记的,而且在重新提出问题之前,将援救声明放在这里感觉有点不枯燥。而你不要想忘记raise声明。如果你这么做了,祝你好运,努力找出那个错误。谢天谢地,Ruby很棒,您可以使用ensure关键字,确保代码运行。这个ensure关键字将运行代码,无论发生什么-如果抛出异常,如果没有异常,唯一的例外是如果世界结束(或其他不可能发生的事件)。 begin      # do driving stuff  ensure     self.airbags.inflate if self.exceeding_safe_stopping_momentum?  end砰!这段代码无论如何都应该运行。你应该用的唯一理由rescue Exception => e是否需要访问异常,或者只希望在异常上运行代码。记得重提错误。每次。注:正如@Niall所指出的,请确保总跑啊。这是好的,因为有时您的程序可以欺骗您,而不是抛出异常,即使发生问题。对于关键的任务,如充气安全气囊,你需要确保它发生在任何情况下。因此,每次停车时检查是否抛出异常都是个好主意。尽管充气气囊在大多数编程环境中是一项不常见的任务,但在大多数清理任务中,这实际上是相当常见的。别rescue Exception => e(而不是重新提出例外)-或者你强权开车离开桥。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Ruby