根据The Ruby Programming Language第164页。
如果
begin
语句没有传播异常,那么该值 语句的评估的最后一个表达式的值begin
,rescue
或else
条款。
但我发现这种行为与开始阻止以及 else子句和确保子句一致。
以下是示例代码:
def fact (n)
raise "bad argument" if n.to_i < 1
end
value = begin
fact (1)
rescue RuntimeError => e
p e.message
else
p "I am in the else statement"
ensure
p "I will be always executed"
p "The END of begin block"
end
p value
输出结果为:
"I am in the else statement"
"I will be always executed"
"The END of begin block"
"I am in the else statement"
[Finished]
value
评估为 else子句。这是不一致的行为,因为 ensure子句是最后执行的语句。
有人可以解释开始区块内发生了什么吗?
答案 0 :(得分:4)
我将begin/rescue/else/end
块的目标解释为:
begin
部分中的代码,然后执行else
部分中的代码。begin
部分出现问题,请执行rescue
部分而不是else
部分。所以 rescue
部分或else
部分将在尝试begin
部分后执行;所以有意义的是,其中一个将被用作整个区块的价值。
这只是副作用,ensure
部分将始终执行。
val = begin
p "first"; "first"
rescue => e
p "fail"; "fail"
else
p "else"; "else"
ensure
p "ensure"; "ensure"
end
val # => "else"
# >> "first"
# >> "else"
# >> "ensure"
可是:
val = begin
p "first"; "first"
raise
rescue => e
p "fail"; "fail"
else
p "else"; "else"
ensure
p "ensure"; "ensure"
end
val # => "fail"
# >> "first"
# >> "fail"
# >> "ensure"
答案 1 :(得分:0)
我只是在这里猜测,但是因为确保块的目的是确定任何可能保持打开的资源(换句话说是清理),所以逻辑值应该是else的结果是有意义的声明。对我来说这是有意义的。
答案 2 :(得分:0)
在这种情况下,begin
块只是一种定义您可能想要进行异常处理的部分的方法。
请记住,如果没有例外,则else
会运行,ensure
将会运行,无论例外情况如何或缺少例外情况。