Ruby Exceptions — Why “else”?
我试图理解Ruby中的异常,但我有点困惑。我使用的教程说,如果发生的异常与rescue语句标识的任何异常都不匹配,可以使用"else"来捕获它:
1 2 3 4 5 6 7 8 9 10 11 | begin # - rescue OneTypeOfException # - rescue AnotherTypeOfException # - else # Other exceptions ensure # Always will be executed end |
不过,我在后面的教程中也看到了"rescue"的用法,没有指定任何异常:
1 2 3 4 5 6 7 8 9 10 | begin file = open("/unexistant_file") if file puts"File opened successfully" end rescue file = STDIN end print file,"==", STDIN," " |
如果你能做到,那我还需要用其他的吗?或者我可以在最后像这样使用一个通用的救援吗?
1 2 3 4 5 6 7 8 9 10 11 | begin # - rescue OneTypeOfException # - rescue AnotherTypeOfException # - rescue # Other exceptions ensure # Always will be executed end |
1 2 3 4 5 6 7 8 9 | begin puts"Hello, world!" rescue puts"rescue" else puts"else" ensure puts"ensure" end |
这将打印
这里是
1 2 3 4 5 6 7 8 9 | def get_error_from(&block) begin block.call rescue => err err # we want to return this else raise"No error was raised" end end |
注意,你不能把
就我个人而言,我很少这样使用
编辑
我遇到了另一个用例。这里有一个典型的
1 2 3 4 5 6 | begin do_something_that_may_raise_argument_error do_something_else_when_the_previous_line_doesnt_raise rescue ArgumentError => e handle_the_error end |
为什么这不太理想?因为目的是当
通常最好使用
- 你可以在不应该出现在
raise 中的代码中隐藏错误。 rescue 的意图很难理解。有人(包括你未来的自己)可能会读到这段代码,想知道"我想保护哪一个表达式?"看起来像是abc…但也许表达定义也一样?????作者的意图是什么?!"重构变得更加困难。
通过这个简单的更改,您可以避免这些问题:
1 2 3 4 5 6 7 | begin do_something_that_may_raise_argument_error rescue ArgumentError => e handle_the_error else do_something_else_when_the_previous_line_doesnt_raise end |
begin rescue end块中的
由于
1 2 3 4 5 6 7 8 9 10 | begin html = begin NetHTTPUtils.request_data url rescue NetHTTPUtils::Error => e raise unless 503 == e.code sleep 60 retry end redo unless html["market"] end |
你写:
1 2 3 4 5 6 7 8 9 | begin html = NetHTTPUtils.request_data url rescue NetHTTPUtils::Error => e raise unless 503 == e.code sleep 60 retry else redo unless html["market"] end |
对于
1 2 3 4 5 6 7 8 9 10 | begin puts"Hello" rescue puts"Error" else puts"Success" ensure puts"my old friend" puts"I've come to talk with you again." end |