According to The Ruby Programming Language p.164.
If a
beginstatement doesn’t propagate an exception, then the value
of the statement is the value of the last expression evaluated in
thebegin,rescueorelseclauses.
But I found this behavior consistent with the begin block together with else clause and ensure clause.
Here is the example code:
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
The output is:
"I am in the else statement"
"I will be always executed"
"The END of begin block"
"I am in the else statement"
[Finished]
The value is evaluated to the else clause. This is inconsistent behavior as the ensure clause is the last statement executed.
Could someone explain what’s happening within the begin block?
I’d interpret the goal of the
begin/rescue/else/endblock as:beginsection, and then the code in theelsesection.beginsection, execute therescuesection instead of theelsesection.So either the
rescuesection or theelsesection will be executed after trying thebeginsection; so it makes sense that one of them will be used as the whole block’s value.It’s simply a side effect that the
ensuresection will always be executed.But: