
186
|
第 6 章
當我們以
m
和
n
的值呼叫
MOD
,而且 Ruby 開始估算 proc 裡的主體時,它會到達
MOD[SUBTRACT[m][n]][n]
的遞迴呼叫,並在引數傳給
IF
的時候,隨即開始估算它,而不
論將
IS_LESS_OR_EQUAL[n][m]
評估成
TRUE
還是
FALSE
。第 2 次呼叫
MOD
會導致另一次無
條件的遞迴呼叫等等,因此就變成無限遞迴。
為了解決這個問題,我們需要有個方式讓 Ruby 知道:直到我們確定需要
IF
的第 2 個
引數之前,Ruby 都先不要估算
IF
的第 2 個引數(也就是延後估算)。Ruby 裡的任何運
算式皆可因包進 proc 而獲得延後估算,但將任意的 Ruby 值包進 proc,通常會改變它
的含義(例如,
1 + 2
的結果不等於
-> {1 + 2}
) ,所以我們可能需要更聰明一點。
所幸我們不需要,因為這是特殊狀況:我們知道呼叫
MOD
的結果將會是個單一引數的
proc,因為我們所有的值都是單一引數的 procs,而且我們已經(從第 170 頁的『相
等』)得知,以另一個 proc 需要相同引數作為
p
並以它們立即呼叫
p
來包裝任何 proc
p
,將會產生無法與
p
區別的值,所以我們可以使用這樣的技巧來延後遞迴呼叫,也不
會影響將值傳進
IF
的含義:
MOD =
-> m { -> n {
IF[IS_LESS_OR_EQUAL[n][m]][
-> x {
MOD[SUBTRACT[m][n]][n][x]
}
][
m
]
} }
這會將遞迴的
MOD
呼叫包進 ...