如何确定开始块的值?
根据The Ruby Programming Language p.164。
如果
begin
语句没有传播exception,则该语句的值是在begin
,rescue
或else
子句中计算的最后一个表达式的值。
但是我发现这个行为与begin块以及else子句和ensure子句一致 。
这是示例代码:
def fact (n) raise "bad argument" if n.to_i 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
将value
else子句 。 这是不一致的行为,因为ensure子句是最后执行的语句。
有人可以解释在开始区块内发生了什么吗?
我将begin/rescue/else/end
块的目标解释为:
- 执行
begin
部分中的代码,然后执行else
部分中的代码。 - 如果在
begin
部分出现问题,请执行rescue
部分而不是else
部分。
因此,在尝试begin
部分之后,将执行rescue
部分或else
部分; 因此,将其中一个用作整个块的值是有道理的。
这只是一个副作用, 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"
我只是在这里猜测,但是由于确保块的目的是最终确定任何可能保持打开的资源(换句话说是清理),因此逻辑值应该是else语句的结果是有意义的。 对我来说这是有意义的。
在这种情况下, begin
块只是一种定义您可能想要进行exception处理的部分的方法。
请记住,在这种情况下,如果没有exception发生,则运行,并ensure
无论exception或缺少exception都会运行。