
50
|
第 2 章
如同任何遞迴程式碼的風險,如果巢狀呼叫的層次太深,Ruby 呼叫堆疊
也有溢位的風險。有些 Ruby 實作物以實驗性質的方式支援
結尾呼叫最
佳化
(
tail call optimization
),這是一種在可能的情況下,重複使用相同
堆疊框而減少溢位風險的技巧。我們能以下列方式開啟官方 Ruby 實作物
(MRI)的結尾呼叫最佳化:
RubyVM::InstructionSequence.compile_option = {
tailcall_optimization: true,
trace_instruction: false
}
為了確認這有正確的運作,我們可以試著估算曾經用來檢查小步語意的相同
«while»
陳述
式:
>> statement =
While.new(
LessThan.new(Variable.new(:x), Number.new(5)),
Assign.new(:x, Multiply.new(Variable.new(:x), Number.new(3)))
)
=> «while (x < 5) { x = x * 3 }»
>> statement.evaluate({ x: Number.new(1) })
=> {:x=>«9»}
它的結果和小步語意的相同,所以
While#evaluate
似乎做了正確的事情。
應用
我們先前在小步語意的實作僅適度使用 Ruby 的呼叫堆疊:當我們在大型程式呼叫
#reduce
的時候,如果訊息往下經過抽象語法樹,然後一直到它抵達準備好化簡的程式碼片段, ...