2012-03-13 15 views
5

The Ruby Programming Languagep.164に従って。開始ブロックの値はどのように決定されますか?

begin文が例外を伝播しない場合は、その文の値 は beginrescueまたは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節に評価されます。これは、の保証条項が実行された最後のステートメントであるため、一貫性のない動作です。

誰かがbeginブロック内で何が起きているのか説明できますか?

+0

"は、コードのブロックが実行された最後の文のために評価されます"。これは明らかに間違った仮定です。 –

+0

申し訳ありませんが、より具体的な声明と参考資料で修正してください。 – steveyang

+2

これであなた自身が質問に答えました。「開始、レスキュー、その他」は実際に正しい順序です。したがって、これは仕様と一致しています。 –

答えて

4

私はとbegin/rescue/else/endブロックの目標を解釈したい:beginセクションのコード、およびelseセクションで、コードを実行し

  • beginセクションで問題が発生した場合は、elseセクションの代わりにrescueセクションを実行してください。

のでいずれかrescueセクションまたはelseセクションでは、beginセクションを試した後に実行されます。そのうちの1つがブロック全体の値として使用されることは意味があります。

これは単に、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" 
0

私はただ推測していますが、確実なブロックの目的は、開いたままのリソース(つまりクリーンアップ)を完成させることであり、論理値はelseステートメント。それは設計上であることが私には意味があります。

0

この場合、beginブロックは、例外処理を行うセクションを定義する単なる方法です。

この場合、例外が発生しなければelseが実行され、例外または不足にかかわらずensureが実行されることを覚えておいてください。

関連する問題