このコードの動作方法は、実際にはスタックトレースとは関係ありません。スタック全体に2つのエントリ、fib
とfib
の呼び出し元があります。例外の発生はあなたの疑問に赤い鳴き声のようなものです。この例では、retry
の動作のデモンストレーション以外の有用な目的はありません。
ルビーのretry
は、next
,break
、redo
などの他の制御キーワードと似ています。 redo
キーワードは、現在のループまたはブロックを先頭から再試行することを意味します。 retry
キーワードはレスキュー内で動作し、例外をスローした現在のブロックを再試行します。
ので、いくつかの初期値はi
、n
、およびresult
に設定され、ここでされて何が起こるか、ベースケースは、(i == -1
)がチェックされ、満たされていない場合、我々は値を更新し、上から再試行してください。これらの値はメソッドパラメータでありローカル変数ではないため、再初期化されないことに注意してください。フィボナッチので
慎重には、再帰的なアルゴリズムのためにこれを間違えないよう、非常に一般的な例(および1つの非常に乏しい)再帰のです。 RunAgain
raiseおよびrescue関数は、関数の呼び出しや呼び出しスタックの修正を行うことなく、ループのように機能します。
あなたのコード例ではi
がちょうどカウンターとの何物でもあり、どちらの場合に注意
def fib(i)
n, result = 1, 0
(i+1).times { n, result = n + result, n }
result
end
に相当します。私たちはコードi+1
回を実行します。値を交換するための一時変数の一般的な必要性は、ルビの複数の代入構造で置き換えられることにも注意してください。
私は大きな値のためにフィボナッチを求めていた場合は、その後上げ千万の例外が存在します。すべての例外情報がスタックに保持されていると、スタックトレースエラーが最終的にスローされます。したがって、私の質問は、スタックトレース情報がスタックから削除され、次の例外が発生したときです。 –
@Nadalは、私の応答の第二の文を参照してください。 「スタック全体の時間の2つのエントリがあります。」あなたの例では、ゼロ再帰を持っており、発生した例外は、スタック上の影響はありません。 –